ClangASTType.cpp revision 535543d6104ee45b4503db6bb6c175e66d0e093b
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/DeclObjC.h"
17#include "clang/AST/DeclGroup.h"
18#include "clang/AST/RecordLayout.h"
19#include "clang/AST/Type.h"
20
21#include "clang/Basic/Builtins.h"
22#include "clang/Basic/IdentifierTable.h"
23#include "clang/Basic/LangOptions.h"
24#include "clang/Basic/SourceManager.h"
25#include "clang/Basic/TargetInfo.h"
26
27#include "llvm/Support/FormattedStream.h"
28#include "llvm/Support/raw_ostream.h"
29
30#include "lldb/Core/ConstString.h"
31#include "lldb/Core/DataBufferHeap.h"
32#include "lldb/Core/DataExtractor.h"
33#include "lldb/Core/Debugger.h"
34#include "lldb/Core/Scalar.h"
35#include "lldb/Core/Stream.h"
36#include "lldb/Core/StreamString.h"
37#include "lldb/Symbol/ClangASTContext.h"
38#include "lldb/Target/ExecutionContext.h"
39#include "lldb/Target/Process.h"
40
41using namespace lldb;
42using namespace lldb_private;
43
44
45ClangASTType::~ClangASTType()
46{
47}
48
49std::string
50ClangASTType::GetTypeNameForQualType (clang::ASTContext *ast, clang::QualType qual_type)
51{
52    std::string type_name;
53
54    clang::PrintingPolicy printing_policy (ast->getPrintingPolicy());
55    printing_policy.SuppressTagKeyword = true;
56    const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
57    if (typedef_type)
58    {
59        const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
60        type_name = typedef_decl->getQualifiedNameAsString(printing_policy);
61    }
62    else
63    {
64        type_name = qual_type.getAsString(printing_policy);
65    }
66    return type_name;
67}
68
69std::string
70ClangASTType::GetTypeNameForOpaqueQualType (clang::ASTContext *ast, clang_type_t opaque_qual_type)
71{
72    return GetTypeNameForQualType (ast, clang::QualType::getFromOpaquePtr(opaque_qual_type));
73}
74
75
76ConstString
77ClangASTType::GetConstTypeName ()
78{
79    // TODO: verify if we actually need to complete a type just to get its type name????
80    if (!ClangASTContext::GetCompleteType (this->m_ast, this->m_type))
81        return ConstString("<invalid>");
82    return GetConstTypeName (m_ast, m_type);
83}
84
85ConstString
86ClangASTType::GetConstQualifiedTypeName ()
87{
88    // TODO: verify if we actually need to complete a type just to get its fully qualified type name????
89    if (!ClangASTContext::GetCompleteType (this->m_ast, this->m_type))
90        return ConstString("<invalid>");
91    return GetConstQualifiedTypeName (m_ast, m_type);
92}
93
94ConstString
95ClangASTType::GetConstQualifiedTypeName (clang::ASTContext *ast, clang_type_t clang_type)
96{
97    if (ast == NULL || clang_type == NULL)
98        return ConstString("<invalid>");
99
100    return ConstString (GetTypeNameForQualType (ast, clang::QualType::getFromOpaquePtr(clang_type)).c_str());
101}
102
103
104ConstString
105ClangASTType::GetConstTypeName (clang::ASTContext *ast, clang_type_t clang_type)
106{
107    if (!clang_type)
108        return ConstString("<invalid>");
109
110    std::string type_name (GetTypeNameForOpaqueQualType(ast, clang_type));
111    ConstString const_type_name;
112    if (type_name.empty())
113        const_type_name.SetCString ("<invalid>");
114    else
115        const_type_name.SetCString(type_name.c_str());
116    return const_type_name;
117}
118
119clang_type_t
120ClangASTType::GetPointeeType ()
121{
122    return GetPointeeType (m_type);
123}
124
125clang_type_t
126ClangASTType::GetPointeeType (clang_type_t clang_type)
127{
128    if (clang_type)
129    {
130        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
131
132        return qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr();
133    }
134    return NULL;
135}
136
137lldb::clang_type_t
138ClangASTType::GetArrayElementType (uint32_t& stride)
139{
140    return GetArrayElementType(m_ast, m_type, stride);
141}
142
143lldb::clang_type_t
144ClangASTType::GetArrayElementType (clang::ASTContext* ast,
145                                   lldb::clang_type_t opaque_clang_qual_type,
146                                   uint32_t& stride)
147{
148    if (opaque_clang_qual_type)
149    {
150        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
151
152        lldb::clang_type_t ret_type = qual_type.getTypePtr()->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified().getAsOpaquePtr();
153
154        // TODO: the real stride will be >= this value.. find the real one!
155        stride = GetTypeByteSize(ast, ret_type);
156
157        return ret_type;
158
159    }
160    return NULL;
161
162}
163
164lldb::clang_type_t
165ClangASTType::GetPointerType () const
166{
167    return GetPointerType (m_ast, m_type);
168}
169
170lldb::clang_type_t
171ClangASTType::GetPointerType (clang::ASTContext *ast_context,
172                              lldb::clang_type_t opaque_clang_qual_type)
173{
174    if (opaque_clang_qual_type)
175    {
176        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
177
178        return ast_context->getPointerType(qual_type).getAsOpaquePtr();
179    }
180    return NULL;
181}
182
183lldb::Encoding
184ClangASTType::GetEncoding (uint32_t &count)
185{
186    return GetEncoding(m_type, count);
187}
188
189
190lldb::LanguageType
191ClangASTType::GetMinimumLanguage ()
192{
193    return ClangASTType::GetMinimumLanguage (m_ast,
194                                             m_type);
195}
196
197lldb::TypeClass
198ClangASTType::GetTypeClass (clang::ASTContext *ast_context, lldb::clang_type_t clang_type)
199{
200    if (clang_type == NULL)
201        return lldb::eTypeClassInvalid;
202
203    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
204
205    switch (qual_type->getTypeClass())
206    {
207        case clang::Type::UnaryTransform:           break;
208        case clang::Type::FunctionNoProto:          return lldb::eTypeClassFunction;
209        case clang::Type::FunctionProto:            return lldb::eTypeClassFunction;
210        case clang::Type::IncompleteArray:          return lldb::eTypeClassArray;
211        case clang::Type::VariableArray:            return lldb::eTypeClassArray;
212        case clang::Type::ConstantArray:            return lldb::eTypeClassArray;
213        case clang::Type::DependentSizedArray:      return lldb::eTypeClassArray;
214        case clang::Type::DependentSizedExtVector:  return lldb::eTypeClassVector;
215        case clang::Type::ExtVector:                return lldb::eTypeClassVector;
216        case clang::Type::Vector:                   return lldb::eTypeClassVector;
217        case clang::Type::Builtin:                  return lldb::eTypeClassBuiltin;
218        case clang::Type::ObjCObjectPointer:        return lldb::eTypeClassObjCObjectPointer;
219        case clang::Type::BlockPointer:             return lldb::eTypeClassBlockPointer;
220        case clang::Type::Pointer:                  return lldb::eTypeClassPointer;
221        case clang::Type::LValueReference:          return lldb::eTypeClassReference;
222        case clang::Type::RValueReference:          return lldb::eTypeClassReference;
223        case clang::Type::MemberPointer:            return lldb::eTypeClassMemberPointer;
224        case clang::Type::Complex:
225            if (qual_type->isComplexType())
226                return lldb::eTypeClassComplexFloat;
227            else
228                return lldb::eTypeClassComplexInteger;
229        case clang::Type::ObjCObject:               return lldb::eTypeClassObjCObject;
230        case clang::Type::ObjCInterface:            return lldb::eTypeClassObjCInterface;
231        case clang::Type::Record:
232            if (ClangASTContext::GetCompleteType (ast_context, clang_type))
233            {
234                const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
235                const clang::RecordDecl *record_decl = record_type->getDecl();
236                if (record_decl->isUnion())
237                    return lldb::eTypeClassUnion;
238                else if (record_decl->isStruct())
239                    return lldb::eTypeClassStruct;
240                else
241                    return lldb::eTypeClassClass;
242            }
243            break;
244        case clang::Type::Enum:                     return lldb::eTypeClassEnumeration;
245        case clang::Type::Typedef:                  return lldb::eTypeClassTypedef;
246        case clang::Type::UnresolvedUsing:          break;
247        case clang::Type::Paren:                    break;
248        case clang::Type::Elaborated:               break;
249        case clang::Type::Attributed:               break;
250        case clang::Type::TemplateTypeParm:         break;
251        case clang::Type::SubstTemplateTypeParm:    break;
252        case clang::Type::SubstTemplateTypeParmPack:break;
253        case clang::Type::Auto:                     break;
254        case clang::Type::InjectedClassName:        break;
255        case clang::Type::DependentName:            break;
256        case clang::Type::DependentTemplateSpecialization: break;
257        case clang::Type::PackExpansion:            break;
258
259        case clang::Type::TypeOfExpr:               break;
260        case clang::Type::TypeOf:                   break;
261        case clang::Type::Decltype:                 break;
262        case clang::Type::TemplateSpecialization:   break;
263        case clang::Type::Atomic:                   break;
264    }
265    // We don't know hot to display this type...
266    return lldb::eTypeClassOther;
267
268}
269
270
271lldb::LanguageType
272ClangASTType::GetMinimumLanguage (clang::ASTContext *ctx,
273                                  lldb::clang_type_t clang_type)
274{
275    if (clang_type == NULL)
276        return lldb::eLanguageTypeC;
277
278    // If the type is a reference, then resolve it to what it refers to first:
279    clang::QualType qual_type (clang::QualType::getFromOpaquePtr(clang_type).getNonReferenceType());
280    if (qual_type->isAnyPointerType())
281    {
282        if (qual_type->isObjCObjectPointerType())
283            return lldb::eLanguageTypeObjC;
284
285        clang::QualType pointee_type (qual_type->getPointeeType());
286        if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
287            return lldb::eLanguageTypeC_plus_plus;
288        if (pointee_type->isObjCObjectOrInterfaceType())
289            return lldb::eLanguageTypeObjC;
290        if (pointee_type->isObjCClassType())
291            return lldb::eLanguageTypeObjC;
292        if (pointee_type.getTypePtr() == ctx->ObjCBuiltinIdTy.getTypePtr())
293            return lldb::eLanguageTypeObjC;
294    }
295    else
296    {
297        if (qual_type->isObjCObjectOrInterfaceType())
298            return lldb::eLanguageTypeObjC;
299        if (qual_type->getAsCXXRecordDecl())
300            return lldb::eLanguageTypeC_plus_plus;
301        switch (qual_type->getTypeClass())
302        {
303        default:
304                break;
305        case clang::Type::Builtin:
306          switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
307            {
308                default:
309                case clang::BuiltinType::Void:
310                case clang::BuiltinType::Bool:
311                case clang::BuiltinType::Char_U:
312                case clang::BuiltinType::UChar:
313                case clang::BuiltinType::WChar_U:
314                case clang::BuiltinType::Char16:
315                case clang::BuiltinType::Char32:
316                case clang::BuiltinType::UShort:
317                case clang::BuiltinType::UInt:
318                case clang::BuiltinType::ULong:
319                case clang::BuiltinType::ULongLong:
320                case clang::BuiltinType::UInt128:
321                case clang::BuiltinType::Char_S:
322                case clang::BuiltinType::SChar:
323                case clang::BuiltinType::WChar_S:
324                case clang::BuiltinType::Short:
325                case clang::BuiltinType::Int:
326                case clang::BuiltinType::Long:
327                case clang::BuiltinType::LongLong:
328                case clang::BuiltinType::Int128:
329                case clang::BuiltinType::Float:
330                case clang::BuiltinType::Double:
331                case clang::BuiltinType::LongDouble:
332                    break;
333
334                case clang::BuiltinType::NullPtr:
335                    return eLanguageTypeC_plus_plus;
336
337                case clang::BuiltinType::ObjCId:
338                case clang::BuiltinType::ObjCClass:
339                case clang::BuiltinType::ObjCSel:
340                    return eLanguageTypeObjC;
341
342                case clang::BuiltinType::Dependent:
343                case clang::BuiltinType::Overload:
344                case clang::BuiltinType::BoundMember:
345                case clang::BuiltinType::UnknownAny:
346                    break;
347            }
348            break;
349        case clang::Type::Typedef:
350            return GetMinimumLanguage(ctx,
351                                      llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
352        }
353    }
354    return lldb::eLanguageTypeC;
355}
356
357lldb::Encoding
358ClangASTType::GetEncoding (clang_type_t clang_type, uint32_t &count)
359{
360    count = 1;
361    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
362
363    switch (qual_type->getTypeClass())
364    {
365    case clang::Type::UnaryTransform:
366        break;
367
368    case clang::Type::FunctionNoProto:
369    case clang::Type::FunctionProto:
370        break;
371
372    case clang::Type::IncompleteArray:
373    case clang::Type::VariableArray:
374        break;
375
376    case clang::Type::ConstantArray:
377        break;
378
379    case clang::Type::ExtVector:
380    case clang::Type::Vector:
381        // TODO: Set this to more than one???
382        break;
383
384    case clang::Type::Builtin:
385        switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
386        {
387        default: assert(0 && "Unknown builtin type!");
388        case clang::BuiltinType::Void:
389            break;
390
391        case clang::BuiltinType::Bool:
392        case clang::BuiltinType::Char_S:
393        case clang::BuiltinType::SChar:
394        case clang::BuiltinType::WChar_S:
395        case clang::BuiltinType::Char16:
396        case clang::BuiltinType::Char32:
397        case clang::BuiltinType::Short:
398        case clang::BuiltinType::Int:
399        case clang::BuiltinType::Long:
400        case clang::BuiltinType::LongLong:
401        case clang::BuiltinType::Int128:        return lldb::eEncodingSint;
402
403        case clang::BuiltinType::Char_U:
404        case clang::BuiltinType::UChar:
405        case clang::BuiltinType::WChar_U:
406        case clang::BuiltinType::UShort:
407        case clang::BuiltinType::UInt:
408        case clang::BuiltinType::ULong:
409        case clang::BuiltinType::ULongLong:
410        case clang::BuiltinType::UInt128:       return lldb::eEncodingUint;
411
412        case clang::BuiltinType::Float:
413        case clang::BuiltinType::Double:
414        case clang::BuiltinType::LongDouble:    return lldb::eEncodingIEEE754;
415
416        case clang::BuiltinType::ObjCClass:
417        case clang::BuiltinType::ObjCId:
418        case clang::BuiltinType::ObjCSel:       return lldb::eEncodingUint;
419
420        case clang::BuiltinType::NullPtr:       return lldb::eEncodingUint;
421        }
422        break;
423    // All pointer types are represented as unsigned integer encodings.
424    // We may nee to add a eEncodingPointer if we ever need to know the
425    // difference
426    case clang::Type::ObjCObjectPointer:
427    case clang::Type::BlockPointer:
428    case clang::Type::Pointer:
429    case clang::Type::LValueReference:
430    case clang::Type::RValueReference:
431    case clang::Type::MemberPointer:            return lldb::eEncodingUint;
432    case clang::Type::Complex:
433        {
434            lldb::Encoding encoding = lldb::eEncodingIEEE754;
435            if (qual_type->isComplexType())
436                encoding = lldb::eEncodingIEEE754;
437            else
438            {
439                const clang::ComplexType *complex_type = qual_type->getAsComplexIntegerType();
440                if (complex_type)
441                    encoding = GetEncoding (complex_type->getElementType().getAsOpaquePtr(), count);
442                else
443                    encoding = lldb::eEncodingSint;
444            }
445            count = 2;
446            return encoding;
447        }
448
449    case clang::Type::ObjCInterface:            break;
450    case clang::Type::Record:                   break;
451    case clang::Type::Enum:                     return lldb::eEncodingSint;
452    case clang::Type::Typedef:
453            return GetEncoding(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), count);
454        break;
455
456    case clang::Type::DependentSizedArray:
457    case clang::Type::DependentSizedExtVector:
458    case clang::Type::UnresolvedUsing:
459    case clang::Type::Paren:
460    case clang::Type::Elaborated:
461    case clang::Type::Attributed:
462    case clang::Type::TemplateTypeParm:
463    case clang::Type::SubstTemplateTypeParm:
464    case clang::Type::SubstTemplateTypeParmPack:
465    case clang::Type::Auto:
466    case clang::Type::InjectedClassName:
467    case clang::Type::DependentName:
468    case clang::Type::DependentTemplateSpecialization:
469    case clang::Type::PackExpansion:
470    case clang::Type::ObjCObject:
471
472    case clang::Type::TypeOfExpr:
473    case clang::Type::TypeOf:
474    case clang::Type::Decltype:
475    case clang::Type::TemplateSpecialization:
476    case clang::Type::Atomic:
477        break;
478
479    }
480    count = 0;
481    return lldb::eEncodingInvalid;
482}
483
484lldb::Format
485ClangASTType::GetFormat ()
486{
487    return GetFormat (m_type);
488}
489
490lldb::Format
491ClangASTType::GetFormat (clang_type_t clang_type)
492{
493    if (clang_type == NULL)
494        return lldb::eFormatDefault;
495
496    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
497
498    switch (qual_type->getTypeClass())
499    {
500    case clang::Type::UnaryTransform:
501        break;
502
503    case clang::Type::FunctionNoProto:
504    case clang::Type::FunctionProto:
505        break;
506
507    case clang::Type::IncompleteArray:
508    case clang::Type::VariableArray:
509        break;
510
511    case clang::Type::ConstantArray:
512        break;
513
514    case clang::Type::ExtVector:
515    case clang::Type::Vector:
516        break;
517
518    case clang::Type::Builtin:
519        switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
520        {
521        //default: assert(0 && "Unknown builtin type!");
522        case clang::BuiltinType::UnknownAny:
523        case clang::BuiltinType::Void:
524        case clang::BuiltinType::BoundMember:
525            break;
526
527        case clang::BuiltinType::Bool:          return lldb::eFormatBoolean;
528        case clang::BuiltinType::Char_S:
529        case clang::BuiltinType::SChar:
530        case clang::BuiltinType::WChar_S:
531        case clang::BuiltinType::Char_U:
532        case clang::BuiltinType::UChar:
533        case clang::BuiltinType::WChar_U:       return lldb::eFormatChar;
534        case clang::BuiltinType::Char16:        return lldb::eFormatUnicode16;
535        case clang::BuiltinType::Char32:        return lldb::eFormatUnicode32;
536        case clang::BuiltinType::UShort:        return lldb::eFormatUnsigned;
537        case clang::BuiltinType::Short:         return lldb::eFormatDecimal;
538        case clang::BuiltinType::UInt:          return lldb::eFormatUnsigned;
539        case clang::BuiltinType::Int:           return lldb::eFormatDecimal;
540        case clang::BuiltinType::ULong:         return lldb::eFormatUnsigned;
541        case clang::BuiltinType::Long:          return lldb::eFormatDecimal;
542        case clang::BuiltinType::ULongLong:     return lldb::eFormatUnsigned;
543        case clang::BuiltinType::LongLong:      return lldb::eFormatDecimal;
544        case clang::BuiltinType::UInt128:       return lldb::eFormatUnsigned;
545        case clang::BuiltinType::Int128:        return lldb::eFormatDecimal;
546        case clang::BuiltinType::Float:         return lldb::eFormatFloat;
547        case clang::BuiltinType::Double:        return lldb::eFormatFloat;
548        case clang::BuiltinType::LongDouble:    return lldb::eFormatFloat;
549        case clang::BuiltinType::NullPtr:
550        case clang::BuiltinType::Overload:
551        case clang::BuiltinType::Dependent:
552        case clang::BuiltinType::ObjCId:
553        case clang::BuiltinType::ObjCClass:
554        case clang::BuiltinType::ObjCSel:
555        case clang::BuiltinType::Half:
556        case clang::BuiltinType::ARCUnbridgedCast:
557        case clang::BuiltinType::PseudoObject:
558            return lldb::eFormatHex;
559        }
560        break;
561    case clang::Type::ObjCObjectPointer:        return lldb::eFormatHex;
562    case clang::Type::BlockPointer:             return lldb::eFormatHex;
563    case clang::Type::Pointer:                  return lldb::eFormatHex;
564    case clang::Type::LValueReference:
565    case clang::Type::RValueReference:          return lldb::eFormatHex;
566    case clang::Type::MemberPointer:            break;
567    case clang::Type::Complex:
568        {
569            if (qual_type->isComplexType())
570                return lldb::eFormatComplex;
571            else
572                return lldb::eFormatComplexInteger;
573        }
574    case clang::Type::ObjCInterface:            break;
575    case clang::Type::Record:                   break;
576    case clang::Type::Enum:                     return lldb::eFormatEnum;
577    case clang::Type::Typedef:
578            return ClangASTType::GetFormat(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
579
580    case clang::Type::Auto:
581            return ClangASTType::GetFormat(llvm::cast<clang::AutoType>(qual_type)->desugar().getAsOpaquePtr());
582    case clang::Type::DependentSizedArray:
583    case clang::Type::DependentSizedExtVector:
584    case clang::Type::UnresolvedUsing:
585    case clang::Type::Paren:
586    case clang::Type::Elaborated:
587    case clang::Type::Attributed:
588    case clang::Type::TemplateTypeParm:
589    case clang::Type::SubstTemplateTypeParm:
590    case clang::Type::SubstTemplateTypeParmPack:
591    case clang::Type::InjectedClassName:
592    case clang::Type::DependentName:
593    case clang::Type::DependentTemplateSpecialization:
594    case clang::Type::PackExpansion:
595    case clang::Type::ObjCObject:
596
597    case clang::Type::TypeOfExpr:
598    case clang::Type::TypeOf:
599    case clang::Type::Decltype:
600    case clang::Type::TemplateSpecialization:
601    case clang::Type::Atomic:
602            break;
603    }
604    // We don't know hot to display this type...
605    return lldb::eFormatBytes;
606}
607
608
609void
610ClangASTType::DumpValue
611(
612    ExecutionContext *exe_ctx,
613    Stream *s,
614    lldb::Format format,
615    const lldb_private::DataExtractor &data,
616    uint32_t data_byte_offset,
617    size_t data_byte_size,
618    uint32_t bitfield_bit_size,
619    uint32_t bitfield_bit_offset,
620    bool show_types,
621    bool show_summary,
622    bool verbose,
623    uint32_t depth
624)
625{
626    return DumpValue (m_ast,
627                      m_type,
628                      exe_ctx,
629                      s,
630                      format,
631                      data,
632                      data_byte_offset,
633                      data_byte_size,
634                      bitfield_bit_size,
635                      bitfield_bit_offset,
636                      show_types,
637                      show_summary,
638                      verbose,
639                      depth);
640}
641
642#define DEPTH_INCREMENT 2
643void
644ClangASTType::DumpValue
645(
646    clang::ASTContext *ast_context,
647    clang_type_t clang_type,
648    ExecutionContext *exe_ctx,
649    Stream *s,
650    lldb::Format format,
651    const lldb_private::DataExtractor &data,
652    uint32_t data_byte_offset,
653    size_t data_byte_size,
654    uint32_t bitfield_bit_size,
655    uint32_t bitfield_bit_offset,
656    bool show_types,
657    bool show_summary,
658    bool verbose,
659    uint32_t depth
660)
661{
662    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
663    switch (qual_type->getTypeClass())
664    {
665    case clang::Type::Record:
666        if (ClangASTContext::GetCompleteType (ast_context, clang_type))
667        {
668            const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
669            const clang::RecordDecl *record_decl = record_type->getDecl();
670            assert(record_decl);
671            uint32_t field_bit_offset = 0;
672            uint32_t field_byte_offset = 0;
673            const clang::ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
674            uint32_t child_idx = 0;
675
676
677            const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
678            if (cxx_record_decl)
679            {
680                // We might have base classes to print out first
681                clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
682                for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
683                     base_class != base_class_end;
684                     ++base_class)
685                {
686                    const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
687
688                    // Skip empty base classes
689                    if (verbose == false && ClangASTContext::RecordHasFields(base_class_decl) == false)
690                        continue;
691
692                    if (base_class->isVirtual())
693                        field_bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
694                    else
695                        field_bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
696                    field_byte_offset = field_bit_offset / 8;
697                    assert (field_bit_offset % 8 == 0);
698                    if (child_idx == 0)
699                        s->PutChar('{');
700                    else
701                        s->PutChar(',');
702
703                    clang::QualType base_class_qual_type = base_class->getType();
704                    std::string base_class_type_name(base_class_qual_type.getAsString());
705
706                    // Indent and print the base class type name
707                    s->Printf("\n%*s%s ", depth + DEPTH_INCREMENT, "", base_class_type_name.c_str());
708
709                    std::pair<uint64_t, unsigned> base_class_type_info = ast_context->getTypeInfo(base_class_qual_type);
710
711                    // Dump the value of the member
712                    DumpValue (ast_context,                        // The clang AST context for this type
713                               base_class_qual_type.getAsOpaquePtr(),// The clang type we want to dump
714                               exe_ctx,
715                               s,                                  // Stream to dump to
716                               ClangASTType::GetFormat(base_class_qual_type.getAsOpaquePtr()), // The format with which to display the member
717                               data,                               // Data buffer containing all bytes for this type
718                               data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
719                               base_class_type_info.first / 8,     // Size of this type in bytes
720                               0,                                  // Bitfield bit size
721                               0,                                  // Bitfield bit offset
722                               show_types,                         // Boolean indicating if we should show the variable types
723                               show_summary,                       // Boolean indicating if we should show a summary for the current type
724                               verbose,                            // Verbose output?
725                               depth + DEPTH_INCREMENT);           // Scope depth for any types that have children
726
727                    ++child_idx;
728                }
729            }
730            uint32_t field_idx = 0;
731            clang::RecordDecl::field_iterator field, field_end;
732            for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
733            {
734                // Print the starting squiggly bracket (if this is the
735                // first member) or comman (for member 2 and beyong) for
736                // the struct/union/class member.
737                if (child_idx == 0)
738                    s->PutChar('{');
739                else
740                    s->PutChar(',');
741
742                // Indent
743                s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
744
745                clang::QualType field_type = field->getType();
746                // Print the member type if requested
747                // Figure out the type byte size (field_type_info.first) and
748                // alignment (field_type_info.second) from the AST context.
749                std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field_type);
750                assert(field_idx < record_layout.getFieldCount());
751                // Figure out the field offset within the current struct/union/class type
752                field_bit_offset = record_layout.getFieldOffset (field_idx);
753                field_byte_offset = field_bit_offset / 8;
754                uint32_t field_bitfield_bit_size = 0;
755                uint32_t field_bitfield_bit_offset = 0;
756                if (ClangASTContext::FieldIsBitfield (ast_context, *field, field_bitfield_bit_size))
757                    field_bitfield_bit_offset = field_bit_offset % 8;
758
759                if (show_types)
760                {
761                    std::string field_type_name(field_type.getAsString());
762                    if (field_bitfield_bit_size > 0)
763                        s->Printf("(%s:%u) ", field_type_name.c_str(), field_bitfield_bit_size);
764                    else
765                        s->Printf("(%s) ", field_type_name.c_str());
766                }
767                // Print the member name and equal sign
768                s->Printf("%s = ", field->getNameAsString().c_str());
769
770
771                // Dump the value of the member
772                DumpValue (ast_context,                    // The clang AST context for this type
773                           field_type.getAsOpaquePtr(),    // The clang type we want to dump
774                           exe_ctx,
775                           s,                              // Stream to dump to
776                           ClangASTType::GetFormat(field_type.getAsOpaquePtr()),   // The format with which to display the member
777                           data,                           // Data buffer containing all bytes for this type
778                           data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
779                           field_type_info.first / 8,      // Size of this type in bytes
780                           field_bitfield_bit_size,        // Bitfield bit size
781                           field_bitfield_bit_offset,      // Bitfield bit offset
782                           show_types,                     // Boolean indicating if we should show the variable types
783                           show_summary,                   // Boolean indicating if we should show a summary for the current type
784                           verbose,                        // Verbose output?
785                           depth + DEPTH_INCREMENT);       // Scope depth for any types that have children
786            }
787
788            // Indent the trailing squiggly bracket
789            if (child_idx > 0)
790                s->Printf("\n%*s}", depth, "");
791        }
792        return;
793
794    case clang::Type::Enum:
795        if (ClangASTContext::GetCompleteType (ast_context, clang_type))
796        {
797            const clang::EnumType *enum_type = llvm::cast<clang::EnumType>(qual_type.getTypePtr());
798            const clang::EnumDecl *enum_decl = enum_type->getDecl();
799            assert(enum_decl);
800            clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
801            uint32_t offset = data_byte_offset;
802            const int64_t enum_value = data.GetMaxU64Bitfield(&offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset);
803            for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
804            {
805                if (enum_pos->getInitVal() == enum_value)
806                {
807                    s->Printf("%s", enum_pos->getNameAsString().c_str());
808                    return;
809                }
810            }
811            // If we have gotten here we didn't get find the enumerator in the
812            // enum decl, so just print the integer.
813            s->Printf("%lli", enum_value);
814        }
815        return;
816
817    case clang::Type::ConstantArray:
818        {
819            const clang::ConstantArrayType *array = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr());
820            bool is_array_of_characters = false;
821            clang::QualType element_qual_type = array->getElementType();
822
823            const clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr();
824            if (canonical_type)
825                is_array_of_characters = canonical_type->isCharType();
826
827            const uint64_t element_count = array->getSize().getLimitedValue();
828
829            std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(element_qual_type);
830
831            uint32_t element_idx = 0;
832            uint32_t element_offset = 0;
833            uint64_t element_byte_size = field_type_info.first / 8;
834            uint32_t element_stride = element_byte_size;
835
836            if (is_array_of_characters)
837            {
838                s->PutChar('"');
839                data.Dump(s, data_byte_offset, lldb::eFormatChar, element_byte_size, element_count, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
840                s->PutChar('"');
841                return;
842            }
843            else
844            {
845                lldb::Format element_format = ClangASTType::GetFormat(element_qual_type.getAsOpaquePtr());
846
847                for (element_idx = 0; element_idx < element_count; ++element_idx)
848                {
849                    // Print the starting squiggly bracket (if this is the
850                    // first member) or comman (for member 2 and beyong) for
851                    // the struct/union/class member.
852                    if (element_idx == 0)
853                        s->PutChar('{');
854                    else
855                        s->PutChar(',');
856
857                    // Indent and print the index
858                    s->Printf("\n%*s[%u] ", depth + DEPTH_INCREMENT, "", element_idx);
859
860                    // Figure out the field offset within the current struct/union/class type
861                    element_offset = element_idx * element_stride;
862
863                    // Dump the value of the member
864                    DumpValue (ast_context,                    // The clang AST context for this type
865                               element_qual_type.getAsOpaquePtr(), // The clang type we want to dump
866                               exe_ctx,
867                               s,                              // Stream to dump to
868                               element_format,                 // The format with which to display the element
869                               data,                           // Data buffer containing all bytes for this type
870                               data_byte_offset + element_offset,// Offset into "data" where to grab value from
871                               element_byte_size,              // Size of this type in bytes
872                               0,                              // Bitfield bit size
873                               0,                              // Bitfield bit offset
874                               show_types,                     // Boolean indicating if we should show the variable types
875                               show_summary,                   // Boolean indicating if we should show a summary for the current type
876                               verbose,                        // Verbose output?
877                               depth + DEPTH_INCREMENT);       // Scope depth for any types that have children
878                }
879
880                // Indent the trailing squiggly bracket
881                if (element_idx > 0)
882                    s->Printf("\n%*s}", depth, "");
883            }
884        }
885        return;
886
887    case clang::Type::Typedef:
888        {
889            clang::QualType typedef_qual_type = llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType();
890            lldb::Format typedef_format = ClangASTType::GetFormat(typedef_qual_type.getAsOpaquePtr());
891            std::pair<uint64_t, unsigned> typedef_type_info = ast_context->getTypeInfo(typedef_qual_type);
892            uint64_t typedef_byte_size = typedef_type_info.first / 8;
893
894            return DumpValue (ast_context,        // The clang AST context for this type
895                              typedef_qual_type.getAsOpaquePtr(), // The clang type we want to dump
896                              exe_ctx,
897                              s,                  // Stream to dump to
898                              typedef_format,     // The format with which to display the element
899                              data,               // Data buffer containing all bytes for this type
900                              data_byte_offset,   // Offset into "data" where to grab value from
901                              typedef_byte_size,  // Size of this type in bytes
902                              bitfield_bit_size,  // Bitfield bit size
903                              bitfield_bit_offset,// Bitfield bit offset
904                              show_types,         // Boolean indicating if we should show the variable types
905                              show_summary,       // Boolean indicating if we should show a summary for the current type
906                              verbose,            // Verbose output?
907                              depth);             // Scope depth for any types that have children
908        }
909        break;
910
911    default:
912        // We are down the a scalar type that we just need to display.
913        data.Dump(s, data_byte_offset, format, data_byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset);
914
915        if (show_summary)
916            DumpSummary (ast_context, clang_type, exe_ctx, s, data, data_byte_offset, data_byte_size);
917        break;
918    }
919}
920
921
922
923bool
924ClangASTType::DumpTypeValue (Stream *s,
925                             lldb::Format format,
926                             const lldb_private::DataExtractor &data,
927                             uint32_t byte_offset,
928                             size_t byte_size,
929                             uint32_t bitfield_bit_size,
930                             uint32_t bitfield_bit_offset,
931                             ExecutionContextScope *exe_scope)
932{
933    return DumpTypeValue (m_ast,
934                          m_type,
935                          s,
936                          format,
937                          data,
938                          byte_offset,
939                          byte_size,
940                          bitfield_bit_size,
941                          bitfield_bit_offset,
942                          exe_scope);
943}
944
945
946bool
947ClangASTType::DumpTypeValue (clang::ASTContext *ast_context,
948                             clang_type_t clang_type,
949                             Stream *s,
950                             lldb::Format format,
951                             const lldb_private::DataExtractor &data,
952                             uint32_t byte_offset,
953                             size_t byte_size,
954                             uint32_t bitfield_bit_size,
955                             uint32_t bitfield_bit_offset,
956                             ExecutionContextScope *exe_scope)
957{
958    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
959    if (ClangASTContext::IsAggregateType (clang_type))
960    {
961        return 0;
962    }
963    else
964    {
965        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
966
967        switch (type_class)
968        {
969        case clang::Type::Typedef:
970            {
971                clang::QualType typedef_qual_type = llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType();
972                if (format == eFormatDefault)
973                    format = ClangASTType::GetFormat(typedef_qual_type.getAsOpaquePtr());
974                std::pair<uint64_t, unsigned> typedef_type_info = ast_context->getTypeInfo(typedef_qual_type);
975                uint64_t typedef_byte_size = typedef_type_info.first / 8;
976
977                return ClangASTType::DumpTypeValue (ast_context,            // The clang AST context for this type
978                                                    typedef_qual_type.getAsOpaquePtr(),     // The clang type we want to dump
979                                                    s,
980                                                    format,                 // The format with which to display the element
981                                                    data,                   // Data buffer containing all bytes for this type
982                                                    byte_offset,            // Offset into "data" where to grab value from
983                                                    typedef_byte_size,      // Size of this type in bytes
984                                                    bitfield_bit_size,      // Size in bits of a bitfield value, if zero don't treat as a bitfield
985                                                    bitfield_bit_offset,    // Offset in bits of a bitfield value if bitfield_bit_size != 0
986                                                    exe_scope);
987            }
988            break;
989
990        case clang::Type::Enum:
991            // If our format is enum or default, show the enumeration value as
992            // its enumeration string value, else just display it as requested.
993            if ((format == eFormatEnum || format == eFormatDefault) && ClangASTContext::GetCompleteType (ast_context, clang_type))
994            {
995                const clang::EnumType *enum_type = llvm::cast<clang::EnumType>(qual_type.getTypePtr());
996                const clang::EnumDecl *enum_decl = enum_type->getDecl();
997                assert(enum_decl);
998                clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
999                uint32_t offset = byte_offset;
1000                const int64_t enum_value = data.GetMaxU64Bitfield (&offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
1001                for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
1002                {
1003                    if (enum_pos->getInitVal() == enum_value)
1004                    {
1005                        s->PutCString (enum_pos->getNameAsString().c_str());
1006                        return true;
1007                    }
1008                }
1009                // If we have gotten here we didn't get find the enumerator in the
1010                // enum decl, so just print the integer.
1011
1012                s->Printf("%lli", enum_value);
1013                return true;
1014            }
1015            // format was not enum, just fall through and dump the value as requested....
1016
1017        default:
1018            // We are down the a scalar type that we just need to display.
1019            {
1020                uint32_t item_count = 1;
1021                // A few formats, we might need to modify our size and count for depending
1022                // on how we are trying to display the value...
1023                switch (format)
1024                {
1025                    default:
1026                    case eFormatBoolean:
1027                    case eFormatBinary:
1028                    case eFormatComplex:
1029                    case eFormatCString:         // NULL terminated C strings
1030                    case eFormatDecimal:
1031                    case eFormatEnum:
1032                    case eFormatHex:
1033                    case eFormatHexUppercase:
1034                    case eFormatFloat:
1035                    case eFormatOctal:
1036                    case eFormatOSType:
1037                    case eFormatUnsigned:
1038                    case eFormatPointer:
1039                    case eFormatVectorOfChar:
1040                    case eFormatVectorOfSInt8:
1041                    case eFormatVectorOfUInt8:
1042                    case eFormatVectorOfSInt16:
1043                    case eFormatVectorOfUInt16:
1044                    case eFormatVectorOfSInt32:
1045                    case eFormatVectorOfUInt32:
1046                    case eFormatVectorOfSInt64:
1047                    case eFormatVectorOfUInt64:
1048                    case eFormatVectorOfFloat32:
1049                    case eFormatVectorOfFloat64:
1050                    case eFormatVectorOfUInt128:
1051                        break;
1052
1053                    case eFormatChar:
1054                    case eFormatCharPrintable:
1055                    case eFormatCharArray:
1056                    case eFormatBytes:
1057                    case eFormatBytesWithASCII:
1058                        item_count = byte_size;
1059                        byte_size = 1;
1060                        break;
1061
1062                    case eFormatUnicode16:
1063                        item_count = byte_size / 2;
1064                        byte_size = 2;
1065                        break;
1066
1067                    case eFormatUnicode32:
1068                        item_count = byte_size / 4;
1069                        byte_size = 4;
1070                        break;
1071                }
1072                return data.Dump (s,
1073                                  byte_offset,
1074                                  format,
1075                                  byte_size,
1076                                  item_count,
1077                                  UINT32_MAX,
1078                                  LLDB_INVALID_ADDRESS,
1079                                  bitfield_bit_size,
1080                                  bitfield_bit_offset,
1081                                  exe_scope);
1082            }
1083            break;
1084        }
1085    }
1086    return 0;
1087}
1088
1089
1090
1091void
1092ClangASTType::DumpSummary
1093(
1094    ExecutionContext *exe_ctx,
1095    Stream *s,
1096    const lldb_private::DataExtractor &data,
1097    uint32_t data_byte_offset,
1098    size_t data_byte_size
1099)
1100{
1101    return DumpSummary (m_ast,
1102                        m_type,
1103                        exe_ctx,
1104                        s,
1105                        data,
1106                        data_byte_offset,
1107                        data_byte_size);
1108}
1109
1110void
1111ClangASTType::DumpSummary
1112(
1113    clang::ASTContext *ast_context,
1114    clang_type_t clang_type,
1115    ExecutionContext *exe_ctx,
1116    Stream *s,
1117    const lldb_private::DataExtractor &data,
1118    uint32_t data_byte_offset,
1119    size_t data_byte_size
1120)
1121{
1122    uint32_t length = 0;
1123    if (ClangASTContext::IsCStringType (clang_type, length))
1124    {
1125        if (exe_ctx)
1126        {
1127            Process *process = exe_ctx->GetProcessPtr();
1128            if (process)
1129            {
1130                uint32_t offset = data_byte_offset;
1131                lldb::addr_t pointer_addresss = data.GetMaxU64(&offset, data_byte_size);
1132                std::vector<uint8_t> buf;
1133                if (length > 0)
1134                    buf.resize (length);
1135                else
1136                    buf.resize (256);
1137
1138                lldb_private::DataExtractor cstr_data(&buf.front(), buf.size(), process->GetByteOrder(), 4);
1139                buf.back() = '\0';
1140                size_t bytes_read;
1141                size_t total_cstr_len = 0;
1142                Error error;
1143                while ((bytes_read = process->ReadMemory (pointer_addresss, &buf.front(), buf.size(), error)) > 0)
1144                {
1145                    const size_t len = strlen((const char *)&buf.front());
1146                    if (len == 0)
1147                        break;
1148                    if (total_cstr_len == 0)
1149                        s->PutCString (" \"");
1150                    cstr_data.Dump(s, 0, lldb::eFormatChar, 1, len, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
1151                    total_cstr_len += len;
1152                    if (len < buf.size())
1153                        break;
1154                    pointer_addresss += total_cstr_len;
1155                }
1156                if (total_cstr_len > 0)
1157                    s->PutChar ('"');
1158            }
1159        }
1160    }
1161}
1162
1163uint32_t
1164ClangASTType::GetClangTypeBitWidth ()
1165{
1166    return GetClangTypeBitWidth (m_ast, m_type);
1167}
1168
1169uint32_t
1170ClangASTType::GetClangTypeBitWidth (clang::ASTContext *ast_context, clang_type_t clang_type)
1171{
1172    if (ClangASTContext::GetCompleteType (ast_context, clang_type))
1173    {
1174        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
1175        return ast_context->getTypeSize (qual_type);
1176    }
1177    return 0;
1178}
1179
1180size_t
1181ClangASTType::GetTypeBitAlign ()
1182{
1183    return GetTypeBitAlign (m_ast, m_type);
1184}
1185
1186size_t
1187ClangASTType::GetTypeBitAlign (clang::ASTContext *ast_context, clang_type_t clang_type)
1188{
1189    if (ClangASTContext::GetCompleteType (ast_context, clang_type))
1190        return ast_context->getTypeAlign(clang::QualType::getFromOpaquePtr(clang_type));
1191    return 0;
1192}
1193
1194
1195bool
1196ClangASTType::IsDefined()
1197{
1198    return ClangASTType::IsDefined (m_type);
1199}
1200
1201bool
1202ClangASTType::IsDefined (clang_type_t clang_type)
1203{
1204    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
1205    const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
1206    if (tag_type)
1207    {
1208        clang::TagDecl *tag_decl = tag_type->getDecl();
1209        if (tag_decl)
1210            return tag_decl->isCompleteDefinition();
1211        return false;
1212    }
1213    else
1214    {
1215        const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
1216        if (objc_class_type)
1217        {
1218            clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1219            if (class_interface_decl)
1220                return class_interface_decl->getDefinition() != NULL;
1221            return false;
1222        }
1223    }
1224    return true;
1225}
1226
1227bool
1228ClangASTType::IsConst()
1229{
1230    return ClangASTType::IsConst (m_type);
1231}
1232
1233bool
1234ClangASTType::IsConst (lldb::clang_type_t clang_type)
1235{
1236    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
1237
1238    return qual_type.isConstQualified();
1239}
1240
1241void
1242ClangASTType::DumpTypeDescription (Stream *s)
1243{
1244    return DumpTypeDescription (m_ast, m_type, s);
1245}
1246
1247// Dump the full description of a type. For classes this means all of the
1248// ivars and member functions, for structs/unions all of the members.
1249void
1250ClangASTType::DumpTypeDescription (clang::ASTContext *ast_context, clang_type_t clang_type, Stream *s)
1251{
1252    if (clang_type)
1253    {
1254        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
1255
1256        llvm::SmallVector<char, 1024> buf;
1257        llvm::raw_svector_ostream llvm_ostrm (buf);
1258
1259        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
1260        switch (type_class)
1261        {
1262        case clang::Type::ObjCObject:
1263        case clang::Type::ObjCInterface:
1264            if (ClangASTContext::GetCompleteType (ast_context, clang_type))
1265            {
1266                const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
1267                assert (objc_class_type);
1268                if (objc_class_type)
1269                {
1270                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
1271                    if (class_interface_decl)
1272                    {
1273                        clang::PrintingPolicy policy = ast_context->getPrintingPolicy();
1274                        policy.Dump = 1;
1275                        class_interface_decl->print(llvm_ostrm, policy, s->GetIndentLevel());
1276                    }
1277                }
1278            }
1279            break;
1280
1281        case clang::Type::Typedef:
1282            {
1283                const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
1284                if (typedef_type)
1285                {
1286                    const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
1287                    std::string clang_typedef_name (typedef_decl->getQualifiedNameAsString());
1288                    if (!clang_typedef_name.empty())
1289                    {
1290                        s->PutCString ("typedef ");
1291                        s->PutCString (clang_typedef_name.c_str());
1292                    }
1293                }
1294            }
1295            break;
1296
1297        case clang::Type::Record:
1298            if (ClangASTContext::GetCompleteType (ast_context, clang_type))
1299            {
1300                const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
1301                const clang::RecordDecl *record_decl = record_type->getDecl();
1302                const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
1303
1304                if (cxx_record_decl)
1305                    cxx_record_decl->print(llvm_ostrm, ast_context->getPrintingPolicy(), s->GetIndentLevel());
1306                else
1307                    record_decl->print(llvm_ostrm, ast_context->getPrintingPolicy(), s->GetIndentLevel());
1308            }
1309            break;
1310
1311        default:
1312            {
1313                const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
1314                if (tag_type)
1315                {
1316                    clang::TagDecl *tag_decl = tag_type->getDecl();
1317                    if (tag_decl)
1318                        tag_decl->print(llvm_ostrm, 0);
1319                }
1320                else
1321                {
1322                    std::string clang_type_name(qual_type.getAsString());
1323                    if (!clang_type_name.empty())
1324                        s->PutCString (clang_type_name.c_str());
1325                }
1326            }
1327        }
1328
1329        llvm_ostrm.flush();
1330        if (buf.size() > 0)
1331        {
1332            s->Write (buf.data(), buf.size());
1333        }
1334    }
1335}
1336
1337void
1338ClangASTType::DumpTypeCode (Stream *s)
1339{
1340    DumpTypeCode(m_type, s);
1341}
1342
1343void
1344ClangASTType::DumpTypeCode (void *type,
1345                            Stream *s)
1346{
1347    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(type));
1348    s->PutCString(qual_type.getAsString().c_str());
1349}
1350
1351bool
1352ClangASTType::GetValueAsScalar
1353(
1354    const lldb_private::DataExtractor &data,
1355    uint32_t data_byte_offset,
1356    size_t data_byte_size,
1357    Scalar &value
1358)
1359{
1360    return GetValueAsScalar (m_ast,
1361                             m_type,
1362                             data,
1363                             data_byte_offset,
1364                             data_byte_size,
1365                             value);
1366}
1367
1368bool
1369ClangASTType::GetValueAsScalar
1370(
1371    clang::ASTContext *ast_context,
1372    clang_type_t clang_type,
1373    const lldb_private::DataExtractor &data,
1374    uint32_t data_byte_offset,
1375    size_t data_byte_size,
1376    Scalar &value
1377)
1378{
1379    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
1380
1381    if (ClangASTContext::IsAggregateType (clang_type))
1382    {
1383        return false;   // Aggregate types don't have scalar values
1384    }
1385    else
1386    {
1387        uint32_t count = 0;
1388        lldb::Encoding encoding = GetEncoding (clang_type, count);
1389
1390        if (encoding == lldb::eEncodingInvalid || count != 1)
1391            return false;
1392
1393        uint64_t bit_width = ast_context->getTypeSize(qual_type);
1394        uint32_t byte_size = (bit_width + 7 ) / 8;
1395        uint32_t offset = data_byte_offset;
1396        switch (encoding)
1397        {
1398        case lldb::eEncodingInvalid:
1399            break;
1400        case lldb::eEncodingVector:
1401            break;
1402        case lldb::eEncodingUint:
1403            if (byte_size <= sizeof(unsigned long long))
1404            {
1405                uint64_t uval64 = data.GetMaxU64 (&offset, byte_size);
1406                if (byte_size <= sizeof(unsigned int))
1407                {
1408                    value = (unsigned int)uval64;
1409                    return true;
1410                }
1411                else if (byte_size <= sizeof(unsigned long))
1412                {
1413                    value = (unsigned long)uval64;
1414                    return true;
1415                }
1416                else if (byte_size <= sizeof(unsigned long long))
1417                {
1418                    value = (unsigned long long )uval64;
1419                    return true;
1420                }
1421                else
1422                    value.Clear();
1423            }
1424            break;
1425
1426        case lldb::eEncodingSint:
1427            if (byte_size <= sizeof(long long))
1428            {
1429                int64_t sval64 = data.GetMaxS64 (&offset, byte_size);
1430                if (byte_size <= sizeof(int))
1431                {
1432                    value = (int)sval64;
1433                    return true;
1434                }
1435                else if (byte_size <= sizeof(long))
1436                {
1437                    value = (long)sval64;
1438                    return true;
1439                }
1440                else if (byte_size <= sizeof(long long))
1441                {
1442                    value = (long long )sval64;
1443                    return true;
1444                }
1445                else
1446                    value.Clear();
1447            }
1448            break;
1449
1450        case lldb::eEncodingIEEE754:
1451            if (byte_size <= sizeof(long double))
1452            {
1453                uint32_t u32;
1454                uint64_t u64;
1455                if (byte_size == sizeof(float))
1456                {
1457                    if (sizeof(float) == sizeof(uint32_t))
1458                    {
1459                        u32 = data.GetU32(&offset);
1460                        value = *((float *)&u32);
1461                        return true;
1462                    }
1463                    else if (sizeof(float) == sizeof(uint64_t))
1464                    {
1465                        u64 = data.GetU64(&offset);
1466                        value = *((float *)&u64);
1467                        return true;
1468                    }
1469                }
1470                else
1471                if (byte_size == sizeof(double))
1472                {
1473                    if (sizeof(double) == sizeof(uint32_t))
1474                    {
1475                        u32 = data.GetU32(&offset);
1476                        value = *((double *)&u32);
1477                        return true;
1478                    }
1479                    else if (sizeof(double) == sizeof(uint64_t))
1480                    {
1481                        u64 = data.GetU64(&offset);
1482                        value = *((double *)&u64);
1483                        return true;
1484                    }
1485                }
1486                else
1487                if (byte_size == sizeof(long double))
1488                {
1489                    if (sizeof(long double) == sizeof(uint32_t))
1490                    {
1491                        u32 = data.GetU32(&offset);
1492                        value = *((long double *)&u32);
1493                        return true;
1494                    }
1495                    else if (sizeof(long double) == sizeof(uint64_t))
1496                    {
1497                        u64 = data.GetU64(&offset);
1498                        value = *((long double *)&u64);
1499                        return true;
1500                    }
1501                }
1502            }
1503            break;
1504        }
1505    }
1506    return false;
1507}
1508
1509bool
1510ClangASTType::SetValueFromScalar (const Scalar &value, Stream &strm)
1511{
1512    return SetValueFromScalar (m_ast, m_type, value, strm);
1513}
1514
1515bool
1516ClangASTType::SetValueFromScalar
1517(
1518    clang::ASTContext *ast_context,
1519    clang_type_t clang_type,
1520    const Scalar &value,
1521    Stream &strm
1522)
1523{
1524    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
1525
1526    // Aggregate types don't have scalar values
1527    if (!ClangASTContext::IsAggregateType (clang_type))
1528    {
1529        strm.GetFlags().Set(Stream::eBinary);
1530        uint32_t count = 0;
1531        lldb::Encoding encoding = GetEncoding (clang_type, count);
1532
1533        if (encoding == lldb::eEncodingInvalid || count != 1)
1534            return false;
1535
1536        uint64_t bit_width = ast_context->getTypeSize(qual_type);
1537        // This function doesn't currently handle non-byte aligned assignments
1538        if ((bit_width % 8) != 0)
1539            return false;
1540
1541        uint32_t byte_size = (bit_width + 7 ) / 8;
1542        switch (encoding)
1543        {
1544        case lldb::eEncodingInvalid:
1545            break;
1546        case lldb::eEncodingVector:
1547            break;
1548        case lldb::eEncodingUint:
1549            switch (byte_size)
1550            {
1551            case 1: strm.PutHex8(value.UInt()); return true;
1552            case 2: strm.PutHex16(value.UInt()); return true;
1553            case 4: strm.PutHex32(value.UInt()); return true;
1554            case 8: strm.PutHex64(value.ULongLong()); return true;
1555            default:
1556                break;
1557            }
1558            break;
1559
1560        case lldb::eEncodingSint:
1561            switch (byte_size)
1562            {
1563            case 1: strm.PutHex8(value.SInt()); return true;
1564            case 2: strm.PutHex16(value.SInt()); return true;
1565            case 4: strm.PutHex32(value.SInt()); return true;
1566            case 8: strm.PutHex64(value.SLongLong()); return true;
1567            default:
1568                break;
1569            }
1570            break;
1571
1572        case lldb::eEncodingIEEE754:
1573            if (byte_size <= sizeof(long double))
1574            {
1575                if (byte_size == sizeof(float))
1576                {
1577                    strm.PutFloat(value.Float());
1578                    return true;
1579                }
1580                else
1581                if (byte_size == sizeof(double))
1582                {
1583                    strm.PutDouble(value.Double());
1584                    return true;
1585                }
1586                else
1587                if (byte_size == sizeof(long double))
1588                {
1589                    strm.PutDouble(value.LongDouble());
1590                    return true;
1591                }
1592            }
1593            break;
1594        }
1595    }
1596    return false;
1597}
1598
1599bool
1600ClangASTType::ReadFromMemory
1601(
1602    lldb_private::ExecutionContext *exe_ctx,
1603    lldb::addr_t addr,
1604    AddressType address_type,
1605    lldb_private::DataExtractor &data
1606)
1607{
1608    return ReadFromMemory (m_ast,
1609                           m_type,
1610                           exe_ctx,
1611                           addr,
1612                           address_type,
1613                           data);
1614}
1615
1616uint32_t
1617ClangASTType::GetTypeByteSize() const
1618{
1619    return GetTypeByteSize(m_ast,
1620                           m_type);
1621}
1622
1623uint32_t
1624ClangASTType::GetTypeByteSize(
1625                clang::ASTContext *ast_context,
1626                lldb::clang_type_t opaque_clang_qual_type)
1627{
1628
1629    if (ClangASTContext::GetCompleteType (ast_context, opaque_clang_qual_type))
1630    {
1631        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
1632        return (ast_context->getTypeSize (qual_type) + 7) / 8;
1633    }
1634    return 0;
1635}
1636
1637
1638bool
1639ClangASTType::ReadFromMemory
1640(
1641    clang::ASTContext *ast_context,
1642    clang_type_t clang_type,
1643    lldb_private::ExecutionContext *exe_ctx,
1644    lldb::addr_t addr,
1645    AddressType address_type,
1646    lldb_private::DataExtractor &data
1647)
1648{
1649    if (address_type == eAddressTypeFile)
1650    {
1651        // Can't convert a file address to anything valid without more
1652        // context (which Module it came from)
1653        return false;
1654    }
1655
1656    if (!ClangASTContext::GetCompleteType(ast_context, clang_type))
1657        return false;
1658
1659    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
1660
1661    const uint32_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
1662    if (data.GetByteSize() < byte_size)
1663    {
1664        lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
1665        data.SetData(data_sp);
1666    }
1667
1668    uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size);
1669    if (dst != NULL)
1670    {
1671        if (address_type == eAddressTypeHost)
1672        {
1673            // The address is an address in this process, so just copy it
1674            memcpy (dst, (uint8_t*)NULL + addr, byte_size);
1675            return true;
1676        }
1677        else
1678        {
1679            Process *process = NULL;
1680            if (exe_ctx)
1681                process = exe_ctx->GetProcessPtr();
1682            if (process)
1683            {
1684                Error error;
1685                return process->ReadMemory(addr, dst, byte_size, error) == byte_size;
1686            }
1687        }
1688    }
1689    return false;
1690}
1691
1692bool
1693ClangASTType::WriteToMemory
1694(
1695    lldb_private::ExecutionContext *exe_ctx,
1696    lldb::addr_t addr,
1697    AddressType address_type,
1698    StreamString &new_value
1699)
1700{
1701    return WriteToMemory (m_ast,
1702                          m_type,
1703                          exe_ctx,
1704                          addr,
1705                          address_type,
1706                          new_value);
1707}
1708
1709bool
1710ClangASTType::WriteToMemory
1711(
1712    clang::ASTContext *ast_context,
1713    clang_type_t clang_type,
1714    lldb_private::ExecutionContext *exe_ctx,
1715    lldb::addr_t addr,
1716    AddressType address_type,
1717    StreamString &new_value
1718)
1719{
1720    if (address_type == eAddressTypeFile)
1721    {
1722        // Can't convert a file address to anything valid without more
1723        // context (which Module it came from)
1724        return false;
1725    }
1726    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
1727    const uint32_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
1728
1729    if (byte_size > 0)
1730    {
1731        if (address_type == eAddressTypeHost)
1732        {
1733            // The address is an address in this process, so just copy it
1734            memcpy ((void *)addr, new_value.GetData(), byte_size);
1735            return true;
1736        }
1737        else
1738        {
1739            Process *process = NULL;
1740            if (exe_ctx)
1741                process = exe_ctx->GetProcessPtr();
1742            if (process)
1743            {
1744                Error error;
1745                return process->WriteMemory(addr, new_value.GetData(), byte_size, error) == byte_size;
1746            }
1747        }
1748    }
1749    return false;
1750}
1751
1752
1753lldb::clang_type_t
1754ClangASTType::RemoveFastQualifiers (lldb::clang_type_t clang_type)
1755{
1756    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
1757    qual_type.getQualifiers().removeFastQualifiers();
1758    return qual_type.getAsOpaquePtr();
1759}
1760
1761
1762bool
1763lldb_private::operator == (const lldb_private::ClangASTType &lhs, const lldb_private::ClangASTType &rhs)
1764{
1765    return lhs.GetASTContext() == rhs.GetASTContext() && lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
1766}
1767
1768
1769bool
1770lldb_private::operator != (const lldb_private::ClangASTType &lhs, const lldb_private::ClangASTType &rhs)
1771{
1772    return lhs.GetASTContext() != rhs.GetASTContext() || lhs.GetOpaqueQualType() != rhs.GetOpaqueQualType();
1773}
1774