blob: 6c831db5e35b0c18904c2f613d55d2846719c71e [file] [log] [blame]
Greg Clayton1674b122010-07-21 22:12:05 +00001//===-- 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 switch (qual_type->getTypeClass())
618 {
619 case clang::Type::Enum:
620 {
621 const clang::EnumType *enum_type = cast<clang::EnumType>(qual_type.getTypePtr());
622 const clang::EnumDecl *enum_decl = enum_type->getDecl();
623 assert(enum_decl);
624 clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
625 uint32_t offset = byte_offset;
626 const int64_t enum_value = data.GetMaxU64Bitfield (&offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
627 for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
628 {
629 if (enum_pos->getInitVal() == enum_value)
630 {
631 s->PutCString (enum_pos->getNameAsCString());
632 return true;
633 }
634 }
635 // If we have gotten here we didn't get find the enumerator in the
636 // enum decl, so just print the integer.
637
638 s->Printf("%lli", enum_value);
639 return true;
640 }
641 break;
642
643 case clang::Type::Typedef:
644 {
645 clang::QualType typedef_qual_type = cast<clang::TypedefType>(qual_type)->LookThroughTypedefs();
646 lldb::Format typedef_format = ClangASTType::GetFormat(typedef_qual_type.getAsOpaquePtr());
647 std::pair<uint64_t, unsigned> typedef_type_info = ast_context->getTypeInfo(typedef_qual_type);
648 uint64_t typedef_byte_size = typedef_type_info.first / 8;
649
650 return ClangASTType::DumpTypeValue(
651 ast_context, // The clang AST context for this type
652 typedef_qual_type.getAsOpaquePtr(), // The clang type we want to dump
653 s,
654 typedef_format, // The format with which to display the element
655 data, // Data buffer containing all bytes for this type
656 byte_offset, // Offset into "data" where to grab value from
657 typedef_byte_size, // Size of this type in bytes
658 bitfield_bit_size, // Size in bits of a bitfield value, if zero don't treat as a bitfield
659 bitfield_bit_offset); // Offset in bits of a bitfield value if bitfield_bit_size != 0
660 }
661 break;
662
663 default:
664 // We are down the a scalar type that we just need to display.
665 return data.Dump(s,
666 byte_offset,
667 format,
668 byte_size,
669 1,
670 UINT32_MAX,
671 LLDB_INVALID_ADDRESS,
672 bitfield_bit_size,
673 bitfield_bit_offset);
674 break;
675 }
676 }
677 return 0;
678}
679
680
681
682void
683ClangASTType::DumpSummary
684(
685 ExecutionContext *exe_ctx,
686 Stream *s,
687 const lldb_private::DataExtractor &data,
688 uint32_t data_byte_offset,
689 size_t data_byte_size
690)
691{
692 return DumpSummary (m_ast,
693 m_type,
694 exe_ctx,
695 s,
696 data,
697 data_byte_offset,
698 data_byte_size);
699}
700
701void
702ClangASTType::DumpSummary
703(
704 clang::ASTContext *ast_context,
705 void *opaque_clang_qual_type,
706 ExecutionContext *exe_ctx,
707 Stream *s,
708 const lldb_private::DataExtractor &data,
709 uint32_t data_byte_offset,
710 size_t data_byte_size
711)
712{
713 uint32_t length = 0;
714 clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
715 if (ClangASTContext::IsCStringType (opaque_clang_qual_type, length))
716 {
717
718 if (exe_ctx && exe_ctx->process)
719 {
720 uint32_t offset = data_byte_offset;
721 lldb::addr_t pointer_addresss = data.GetMaxU64(&offset, data_byte_size);
722 std::vector<uint8_t> buf;
723 if (length > 0)
724 buf.resize (length);
725 else
726 buf.resize (256);
727
728 lldb_private::DataExtractor cstr_data(&buf.front(), buf.size(), exe_ctx->process->GetByteOrder(), 4);
729 buf.back() = '\0';
730 size_t bytes_read;
731 size_t total_cstr_len = 0;
732 Error error;
733 while ((bytes_read = exe_ctx->process->ReadMemory (pointer_addresss, &buf.front(), buf.size(), error)) > 0)
734 {
735 const size_t len = strlen((const char *)&buf.front());
736 if (len == 0)
737 break;
738 if (total_cstr_len == 0)
739 s->PutCString (" \"");
740 cstr_data.Dump(s, 0, lldb::eFormatChar, 1, len, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
741 total_cstr_len += len;
742 if (len < buf.size())
743 break;
744 pointer_addresss += total_cstr_len;
745 }
746 if (total_cstr_len > 0)
747 s->PutChar ('"');
748 }
749 }
750}
751
752bool
753ClangASTType::GetValueAsScalar
754(
755 const lldb_private::DataExtractor &data,
756 uint32_t data_byte_offset,
757 size_t data_byte_size,
758 Scalar &value
759)
760{
761 return GetValueAsScalar (m_ast,
762 m_type,
763 data,
764 data_byte_offset,
765 data_byte_size,
766 value);
767}
768
769bool
770ClangASTType::GetValueAsScalar
771(
772 clang::ASTContext *ast_context,
773 void *opaque_clang_qual_type,
774 const lldb_private::DataExtractor &data,
775 uint32_t data_byte_offset,
776 size_t data_byte_size,
777 Scalar &value
778)
779{
780 clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
781
782 if (ClangASTContext::IsAggregateType (opaque_clang_qual_type))
783 {
784 return false; // Aggregate types don't have scalar values
785 }
786 else
787 {
788 uint32_t count = 0;
789 lldb::Encoding encoding = GetEncoding (opaque_clang_qual_type, count);
790
791 if (encoding == lldb::eEncodingInvalid || count != 1)
792 return false;
793
794 uint64_t bit_width = ast_context->getTypeSize(qual_type);
795 uint32_t byte_size = (bit_width + 7 ) / 8;
796 uint32_t offset = data_byte_offset;
797 switch (encoding)
798 {
799 case lldb::eEncodingUint:
800 if (byte_size <= sizeof(unsigned long long))
801 {
802 uint64_t uval64 = data.GetMaxU64 (&offset, byte_size);
803 if (byte_size <= sizeof(unsigned int))
804 {
805 value = (unsigned int)uval64;
806 return true;
807 }
808 else if (byte_size <= sizeof(unsigned long))
809 {
810 value = (unsigned long)uval64;
811 return true;
812 }
813 else if (byte_size <= sizeof(unsigned long long))
814 {
815 value = (unsigned long long )uval64;
816 return true;
817 }
818 else
819 value.Clear();
820 }
821 break;
822
823 case lldb::eEncodingSint:
824 if (byte_size <= sizeof(long long))
825 {
826 int64_t sval64 = (int64_t)data.GetMaxU64 (&offset, byte_size);
827 if (byte_size <= sizeof(int))
828 {
829 value = (int)sval64;
830 return true;
831 }
832 else if (byte_size <= sizeof(long))
833 {
834 value = (long)sval64;
835 return true;
836 }
837 else if (byte_size <= sizeof(long long))
838 {
839 value = (long long )sval64;
840 return true;
841 }
842 else
843 value.Clear();
844 }
845 break;
846
847 case lldb::eEncodingIEEE754:
848 if (byte_size <= sizeof(long double))
849 {
850 uint32_t u32;
851 uint64_t u64;
852 if (byte_size == sizeof(float))
853 {
854 if (sizeof(float) == sizeof(uint32_t))
855 {
856 u32 = data.GetU32(&offset);
857 value = *((float *)&u32);
858 return true;
859 }
860 else if (sizeof(float) == sizeof(uint64_t))
861 {
862 u64 = data.GetU64(&offset);
863 value = *((float *)&u64);
864 return true;
865 }
866 }
867 else
868 if (byte_size == sizeof(double))
869 {
870 if (sizeof(double) == sizeof(uint32_t))
871 {
872 u32 = data.GetU32(&offset);
873 value = *((double *)&u32);
874 return true;
875 }
876 else if (sizeof(double) == sizeof(uint64_t))
877 {
878 u64 = data.GetU64(&offset);
879 value = *((double *)&u64);
880 return true;
881 }
882 }
883 else
884 if (byte_size == sizeof(long double))
885 {
886 if (sizeof(long double) == sizeof(uint32_t))
887 {
888 u32 = data.GetU32(&offset);
889 value = *((long double *)&u32);
890 return true;
891 }
892 else if (sizeof(long double) == sizeof(uint64_t))
893 {
894 u64 = data.GetU64(&offset);
895 value = *((long double *)&u64);
896 return true;
897 }
898 }
899 }
900 break;
901 }
902 }
903 return false;
904}
905
906bool
907ClangASTType::SetValueFromScalar (const Scalar &value, Stream &strm)
908{
909 return SetValueFromScalar (m_ast, m_type, value, strm);
910}
911
912bool
913ClangASTType::SetValueFromScalar
914(
915 clang::ASTContext *ast_context,
916 void *opaque_clang_qual_type,
917 const Scalar &value,
918 Stream &strm
919)
920{
921 clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
922
923 // Aggregate types don't have scalar values
924 if (!ClangASTContext::IsAggregateType (opaque_clang_qual_type))
925 {
926 strm.GetFlags().Set(Stream::eBinary);
927 uint32_t count = 0;
928 lldb::Encoding encoding = GetEncoding (opaque_clang_qual_type, count);
929
930 if (encoding == lldb::eEncodingInvalid || count != 1)
931 return false;
932
933 uint64_t bit_width = ast_context->getTypeSize(qual_type);
934 // This function doesn't currently handle non-byte aligned assignments
935 if ((bit_width % 8) != 0)
936 return false;
937
938 uint32_t byte_size = (bit_width + 7 ) / 8;
939 switch (encoding)
940 {
941 case lldb::eEncodingUint:
942 switch (byte_size)
943 {
944 case 1: strm.PutHex8(value.UInt()); return true;
945 case 2: strm.PutHex16(value.UInt()); return true;
946 case 4: strm.PutHex32(value.UInt()); return true;
947 case 8: strm.PutHex64(value.ULongLong()); return true;
948 default:
949 break;
950 }
951 break;
952
953 case lldb::eEncodingSint:
954 switch (byte_size)
955 {
956 case 1: strm.PutHex8(value.SInt()); return true;
957 case 2: strm.PutHex16(value.SInt()); return true;
958 case 4: strm.PutHex32(value.SInt()); return true;
959 case 8: strm.PutHex64(value.SLongLong()); return true;
960 default:
961 break;
962 }
963 break;
964
965 case lldb::eEncodingIEEE754:
966 if (byte_size <= sizeof(long double))
967 {
968 if (byte_size == sizeof(float))
969 {
970 strm.PutFloat(value.Float());
971 return true;
972 }
973 else
974 if (byte_size == sizeof(double))
975 {
976 strm.PutDouble(value.Double());
977 return true;
978 }
979 else
980 if (byte_size == sizeof(long double))
981 {
982 strm.PutDouble(value.LongDouble());
983 return true;
984 }
985 }
986 break;
987 }
988 }
989 return false;
990}
991
992bool
993ClangASTType::ReadFromMemory
994(
995 lldb_private::ExecutionContext *exe_ctx,
996 lldb::addr_t addr,
997 lldb::AddressType address_type,
998 lldb_private::DataExtractor &data
999)
1000{
1001 return ReadFromMemory (m_ast,
1002 m_type,
1003 exe_ctx,
1004 addr,
1005 address_type,
1006 data);
1007}
1008
1009
1010bool
1011ClangASTType::ReadFromMemory
1012(
1013 clang::ASTContext *ast_context,
1014 void *opaque_clang_qual_type,
1015 lldb_private::ExecutionContext *exe_ctx,
1016 lldb::addr_t addr,
1017 lldb::AddressType address_type,
1018 lldb_private::DataExtractor &data
1019)
1020{
1021 if (address_type == lldb::eAddressTypeFile)
1022 {
1023 // Can't convert a file address to anything valid without more
1024 // context (which Module it came from)
1025 return false;
1026 }
1027 clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
1028
1029 const uint32_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
1030 if (data.GetByteSize() < byte_size)
1031 {
1032 lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
1033 data.SetData(data_sp);
1034 }
1035
1036 uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size);
1037 if (dst != NULL)
1038 {
1039 if (address_type == lldb::eAddressTypeHost)
1040 {
1041 // The address is an address in this process, so just copy it
1042 memcpy (dst, (uint8_t*)NULL + addr, byte_size);
1043 return true;
1044 }
1045 else
1046 {
1047 if (exe_ctx && exe_ctx->process)
1048 {
1049 Error error;
1050 return exe_ctx->process->ReadMemory(addr, dst, byte_size, error) == byte_size;
1051 }
1052 }
1053 }
1054 return false;
1055}
1056
1057bool
1058ClangASTType::WriteToMemory
1059(
1060 lldb_private::ExecutionContext *exe_ctx,
1061 lldb::addr_t addr,
1062 lldb::AddressType address_type,
1063 StreamString &new_value
1064)
1065{
1066 return WriteToMemory (m_ast,
1067 m_type,
1068 exe_ctx,
1069 addr,
1070 address_type,
1071 new_value);
1072}
1073
1074bool
1075ClangASTType::WriteToMemory
1076(
1077 clang::ASTContext *ast_context,
1078 void *opaque_clang_qual_type,
1079 lldb_private::ExecutionContext *exe_ctx,
1080 lldb::addr_t addr,
1081 lldb::AddressType address_type,
1082 StreamString &new_value
1083)
1084{
1085 if (address_type == lldb::eAddressTypeFile)
1086 {
1087 // Can't convert a file address to anything valid without more
1088 // context (which Module it came from)
1089 return false;
1090 }
1091 clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
1092 const uint32_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
1093
1094 if (byte_size > 0)
1095 {
1096 if (address_type == lldb::eAddressTypeHost)
1097 {
1098 // The address is an address in this process, so just copy it
1099 memcpy ((void *)addr, new_value.GetData(), byte_size);
1100 return true;
1101 }
1102 else
1103 {
1104 if (exe_ctx && exe_ctx->process)
1105 {
1106 Error error;
1107 return exe_ctx->process->WriteMemory(addr, new_value.GetData(), byte_size, error) == byte_size;
1108 }
1109 }
1110 }
1111 return false;
1112}
1113
1114