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