1 //===-- Type.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 // Other libraries and framework includes 11 12 #include "lldb/Core/DataExtractor.h" 13 #include "lldb/Core/DataBufferHeap.h" 14 #include "lldb/Core/Module.h" 15 #include "lldb/Core/Scalar.h" 16 #include "lldb/Core/StreamString.h" 17 18 #include "lldb/Symbol/ClangASTType.h" 19 #include "lldb/Symbol/ClangASTContext.h" 20 #include "lldb/Symbol/ObjectFile.h" 21 #include "lldb/Symbol/SymbolContextScope.h" 22 #include "lldb/Symbol/SymbolFile.h" 23 #include "lldb/Symbol/Type.h" 24 #include "lldb/Symbol/TypeList.h" 25 26 #include "lldb/Target/ExecutionContext.h" 27 #include "lldb/Target/Process.h" 28 #include "lldb/Target/Target.h" 29 30 using namespace lldb; 31 using namespace lldb_private; 32 33 Type::Type 34 ( 35 lldb::user_id_t uid, 36 SymbolFile* symbol_file, 37 const ConstString &name, 38 uint32_t byte_size, 39 SymbolContextScope *context, 40 user_id_t encoding_uid, 41 EncodingDataType encoding_uid_type, 42 const Declaration& decl, 43 clang_type_t clang_type, 44 ResolveState clang_type_resolve_state 45 ) : 46 UserID (uid), 47 m_name (name), 48 m_symbol_file (symbol_file), 49 m_context (context), 50 m_encoding_type (NULL), 51 m_encoding_uid (encoding_uid), 52 m_encoding_uid_type (encoding_uid_type), 53 m_byte_size (byte_size), 54 m_decl (decl), 55 m_clang_type (clang_type), 56 m_clang_type_resolve_state (clang_type ? clang_type_resolve_state : eResolveStateUnresolved) 57 { 58 } 59 60 Type::Type () : 61 UserID (0), 62 m_name ("<INVALID TYPE>"), 63 m_symbol_file (NULL), 64 m_context (NULL), 65 m_encoding_type (NULL), 66 m_encoding_uid (0), 67 m_encoding_uid_type (eEncodingInvalid), 68 m_byte_size (0), 69 m_decl (), 70 m_clang_type (NULL), 71 m_clang_type_resolve_state (eResolveStateUnresolved) 72 { 73 } 74 75 76 Type::Type (const Type &rhs) : 77 UserID (rhs), 78 m_name (rhs.m_name), 79 m_symbol_file (rhs.m_symbol_file), 80 m_context (rhs.m_context), 81 m_encoding_type (rhs.m_encoding_type), 82 m_encoding_uid (rhs.m_encoding_uid), 83 m_encoding_uid_type (rhs.m_encoding_uid_type), 84 m_byte_size (rhs.m_byte_size), 85 m_decl (rhs.m_decl), 86 m_clang_type (rhs.m_clang_type), 87 m_clang_type_resolve_state (rhs.m_clang_type_resolve_state) 88 { 89 } 90 91 const Type& 92 Type::operator= (const Type& rhs) 93 { 94 if (this != &rhs) 95 { 96 } 97 return *this; 98 } 99 100 101 void 102 Type::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_name) 103 { 104 *s << "id = " << (const UserID&)*this; 105 106 // Call the name accessor to make sure we resolve the type name 107 if (show_name && GetName()) 108 *s << ", name = \"" << m_name << '"'; 109 110 // Call the get byte size accesor so we resolve our byte size 111 if (GetByteSize()) 112 s->Printf(", byte-size = %zu", m_byte_size); 113 bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose); 114 m_decl.Dump(s, show_fullpaths); 115 116 if (m_clang_type) 117 { 118 *s << ", clang_type = \""; 119 ClangASTType::DumpTypeDescription (GetClangAST(), m_clang_type, s); 120 *s << '"'; 121 } 122 else if (m_encoding_uid != LLDB_INVALID_UID) 123 { 124 s->Printf(", type_uid = 0x%8.8x", m_encoding_uid); 125 switch (m_encoding_uid_type) 126 { 127 case eEncodingInvalid: break; 128 case eEncodingIsUID: s->PutCString(" (unresolved type)"); break; 129 case eEncodingIsConstUID: s->PutCString(" (unresolved const type)"); break; 130 case eEncodingIsRestrictUID: s->PutCString(" (unresolved restrict type)"); break; 131 case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break; 132 case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break; 133 case eEncodingIsPointerUID: s->PutCString(" (unresolved pointer)"); break; 134 case eEncodingIsLValueReferenceUID: s->PutCString(" (unresolved L value reference)"); break; 135 case eEncodingIsRValueReferenceUID: s->PutCString(" (unresolved R value reference)"); break; 136 case eEncodingIsSyntheticUID: s->PutCString(" (synthetic type)"); break; 137 } 138 } 139 } 140 141 142 void 143 Type::Dump (Stream *s, bool show_context) 144 { 145 s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 146 s->Indent(); 147 *s << "Type" << (const UserID&)*this << ' '; 148 if (m_name) 149 *s << ", name = \"" << m_name << "\""; 150 151 if (m_byte_size != 0) 152 s->Printf(", size = %zu", m_byte_size); 153 154 if (show_context && m_context != NULL) 155 { 156 s->PutCString(", context = ( "); 157 m_context->DumpSymbolContext(s); 158 s->PutCString(" )"); 159 } 160 161 bool show_fullpaths = false; 162 m_decl.Dump (s,show_fullpaths); 163 164 if (m_clang_type) 165 { 166 *s << ", clang_type = " << m_clang_type << ' '; 167 168 ClangASTType::DumpTypeDescription (GetClangAST(), m_clang_type, s); 169 } 170 else if (m_encoding_uid != LLDB_INVALID_UID) 171 { 172 *s << ", type_data = " << (uint64_t)m_encoding_uid; 173 switch (m_encoding_uid_type) 174 { 175 case eEncodingInvalid: break; 176 case eEncodingIsUID: s->PutCString(" (unresolved type)"); break; 177 case eEncodingIsConstUID: s->PutCString(" (unresolved const type)"); break; 178 case eEncodingIsRestrictUID: s->PutCString(" (unresolved restrict type)"); break; 179 case eEncodingIsVolatileUID: s->PutCString(" (unresolved volatile type)"); break; 180 case eEncodingIsTypedefUID: s->PutCString(" (unresolved typedef)"); break; 181 case eEncodingIsPointerUID: s->PutCString(" (unresolved pointer)"); break; 182 case eEncodingIsLValueReferenceUID: s->PutCString(" (unresolved L value reference)"); break; 183 case eEncodingIsRValueReferenceUID: s->PutCString(" (unresolved R value reference)"); break; 184 case eEncodingIsSyntheticUID: s->PutCString(" (synthetic type)"); break; 185 } 186 } 187 188 // 189 // if (m_access) 190 // s->Printf(", access = %u", m_access); 191 s->EOL(); 192 } 193 194 const ConstString & 195 Type::GetName() 196 { 197 if (!m_name) 198 { 199 if (ResolveClangType(eResolveStateForward)) 200 m_name = ClangASTType::GetConstTypeName (m_clang_type); 201 } 202 return m_name; 203 } 204 205 void 206 Type::DumpTypeName(Stream *s) 207 { 208 GetName().Dump(s, "<invalid-type-name>"); 209 } 210 211 212 void 213 Type::DumpValue 214 ( 215 ExecutionContext *exe_ctx, 216 Stream *s, 217 const DataExtractor &data, 218 uint32_t data_byte_offset, 219 bool show_types, 220 bool show_summary, 221 bool verbose, 222 lldb::Format format 223 ) 224 { 225 if (ResolveClangType(eResolveStateForward)) 226 { 227 if (show_types) 228 { 229 s->PutChar('('); 230 if (verbose) 231 s->Printf("Type{0x%8.8x} ", GetID()); 232 DumpTypeName (s); 233 s->PutCString(") "); 234 } 235 236 ClangASTType::DumpValue (GetClangAST (), 237 m_clang_type, 238 exe_ctx, 239 s, 240 format == lldb::eFormatDefault ? GetFormat() : format, 241 data, 242 data_byte_offset, 243 GetByteSize(), 244 0, // Bitfield bit size 245 0, // Bitfield bit offset 246 show_types, 247 show_summary, 248 verbose, 249 0); 250 } 251 } 252 253 Type * 254 Type::GetEncodingType () 255 { 256 if (m_encoding_type == NULL && m_encoding_uid != LLDB_INVALID_UID) 257 m_encoding_type = m_symbol_file->ResolveTypeUID(m_encoding_uid); 258 return m_encoding_type; 259 } 260 261 262 263 uint32_t 264 Type::GetByteSize() 265 { 266 if (m_byte_size == 0) 267 { 268 switch (m_encoding_uid_type) 269 { 270 case eEncodingInvalid: 271 case eEncodingIsSyntheticUID: 272 break; 273 case eEncodingIsUID: 274 case eEncodingIsConstUID: 275 case eEncodingIsRestrictUID: 276 case eEncodingIsVolatileUID: 277 case eEncodingIsTypedefUID: 278 { 279 Type *encoding_type = GetEncodingType (); 280 if (encoding_type) 281 m_byte_size = encoding_type->GetByteSize(); 282 if (m_byte_size == 0) 283 { 284 uint32_t bit_width = ClangASTType::GetClangTypeBitWidth (GetClangAST(), GetClangLayoutType()); 285 m_byte_size = (bit_width + 7 ) / 8; 286 } 287 } 288 break; 289 290 // If we are a pointer or reference, then this is just a pointer size; 291 case eEncodingIsPointerUID: 292 case eEncodingIsLValueReferenceUID: 293 case eEncodingIsRValueReferenceUID: 294 m_byte_size = m_symbol_file->GetClangASTContext().GetPointerBitSize() / 8; 295 break; 296 } 297 } 298 return m_byte_size; 299 } 300 301 302 uint32_t 303 Type::GetNumChildren (bool omit_empty_base_classes) 304 { 305 if (ResolveClangType(eResolveStateForward)) 306 { 307 return ClangASTContext::GetNumChildren (m_symbol_file->GetClangASTContext().getASTContext(), 308 m_clang_type, 309 omit_empty_base_classes); 310 } 311 return 0; 312 } 313 314 bool 315 Type::IsAggregateType () 316 { 317 if (ResolveClangType(eResolveStateForward)) 318 return ClangASTContext::IsAggregateType (m_clang_type); 319 return false; 320 } 321 322 lldb::Format 323 Type::GetFormat () 324 { 325 // Make sure we resolve our type if it already hasn't been. 326 if (!ResolveClangType(eResolveStateForward)) 327 return lldb::eFormatInvalid; 328 return ClangASTType::GetFormat (m_clang_type); 329 } 330 331 332 333 lldb::Encoding 334 Type::GetEncoding (uint32_t &count) 335 { 336 // Make sure we resolve our type if it already hasn't been. 337 if (!ResolveClangType(eResolveStateForward)) 338 return lldb::eEncodingInvalid; 339 340 return ClangASTType::GetEncoding (m_clang_type, count); 341 } 342 343 344 345 bool 346 Type::DumpValueInMemory 347 ( 348 ExecutionContext *exe_ctx, 349 Stream *s, 350 lldb::addr_t address, 351 AddressType address_type, 352 bool show_types, 353 bool show_summary, 354 bool verbose 355 ) 356 { 357 if (address != LLDB_INVALID_ADDRESS) 358 { 359 DataExtractor data; 360 if (exe_ctx->target) 361 data.SetByteOrder (exe_ctx->target->GetArchitecture().GetByteOrder()); 362 if (ReadFromMemory (exe_ctx, address, address_type, data)) 363 { 364 DumpValue(exe_ctx, s, data, 0, show_types, show_summary, verbose); 365 return true; 366 } 367 } 368 return false; 369 } 370 371 372 bool 373 Type::ReadFromMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data) 374 { 375 if (address_type == eAddressTypeFile) 376 { 377 // Can't convert a file address to anything valid without more 378 // context (which Module it came from) 379 return false; 380 } 381 382 const uint32_t byte_size = GetByteSize(); 383 if (data.GetByteSize() < byte_size) 384 { 385 lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0')); 386 data.SetData(data_sp); 387 } 388 389 uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size); 390 if (dst != NULL) 391 { 392 if (address_type == eAddressTypeHost) 393 { 394 // The address is an address in this process, so just copy it 395 memcpy (dst, (uint8_t*)NULL + addr, byte_size); 396 return true; 397 } 398 else 399 { 400 if (exe_ctx && exe_ctx->process) 401 { 402 Error error; 403 return exe_ctx->process->ReadMemory(addr, dst, byte_size, error) == byte_size; 404 } 405 } 406 } 407 return false; 408 } 409 410 411 bool 412 Type::WriteToMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data) 413 { 414 return false; 415 } 416 417 418 TypeList* 419 Type::GetTypeList() 420 { 421 return GetSymbolFile()->GetTypeList(); 422 } 423 424 const Declaration & 425 Type::GetDeclaration () const 426 { 427 return m_decl; 428 } 429 430 bool 431 Type::ResolveClangType (ResolveState clang_type_resolve_state) 432 { 433 Type *encoding_type = NULL; 434 if (m_clang_type == NULL) 435 { 436 encoding_type = GetEncodingType(); 437 if (encoding_type) 438 { 439 switch (m_encoding_uid_type) 440 { 441 case eEncodingIsUID: 442 if (encoding_type->ResolveClangType(clang_type_resolve_state)) 443 { 444 m_clang_type = encoding_type->m_clang_type; 445 m_clang_type_resolve_state = encoding_type->m_clang_type_resolve_state; 446 } 447 break; 448 449 case eEncodingIsConstUID: 450 m_clang_type = ClangASTContext::AddConstModifier (encoding_type->GetClangForwardType()); 451 break; 452 453 case eEncodingIsRestrictUID: 454 m_clang_type = ClangASTContext::AddRestrictModifier (encoding_type->GetClangForwardType()); 455 break; 456 457 case eEncodingIsVolatileUID: 458 m_clang_type = ClangASTContext::AddVolatileModifier (encoding_type->GetClangForwardType()); 459 break; 460 461 case eEncodingIsTypedefUID: 462 m_clang_type = CreateClangTypedefType (this, encoding_type); 463 // Clear the name so it can get fully qualified in case the 464 // typedef is in a namespace. 465 m_name.Clear(); 466 break; 467 468 case eEncodingIsPointerUID: 469 m_clang_type = CreateClangPointerType (encoding_type); 470 break; 471 472 case eEncodingIsLValueReferenceUID: 473 m_clang_type = CreateClangLValueReferenceType (encoding_type); 474 break; 475 476 case eEncodingIsRValueReferenceUID: 477 m_clang_type = CreateClangRValueReferenceType (encoding_type); 478 break; 479 480 default: 481 assert(!"Unhandled encoding_data_type."); 482 break; 483 } 484 } 485 else 486 { 487 // We have no encoding type, return void? 488 clang_type_t void_clang_type = GetClangASTContext().GetBuiltInType_void(); 489 switch (m_encoding_uid_type) 490 { 491 case eEncodingIsUID: 492 m_clang_type = void_clang_type; 493 break; 494 495 case eEncodingIsConstUID: 496 m_clang_type = ClangASTContext::AddConstModifier (void_clang_type); 497 break; 498 499 case eEncodingIsRestrictUID: 500 m_clang_type = ClangASTContext::AddRestrictModifier (void_clang_type); 501 break; 502 503 case eEncodingIsVolatileUID: 504 m_clang_type = ClangASTContext::AddVolatileModifier (void_clang_type); 505 break; 506 507 case eEncodingIsTypedefUID: 508 m_clang_type = GetClangASTContext().CreateTypedefType (m_name.AsCString(), void_clang_type, NULL); 509 break; 510 511 case eEncodingIsPointerUID: 512 m_clang_type = GetClangASTContext().CreatePointerType (void_clang_type); 513 break; 514 515 case eEncodingIsLValueReferenceUID: 516 m_clang_type = GetClangASTContext().CreateLValueReferenceType (void_clang_type); 517 break; 518 519 case eEncodingIsRValueReferenceUID: 520 m_clang_type = GetClangASTContext().CreateRValueReferenceType (void_clang_type); 521 break; 522 523 default: 524 assert(!"Unhandled encoding_data_type."); 525 break; 526 } 527 } 528 } 529 530 // Check if we have a forward reference to a class/struct/union/enum? 531 if (m_clang_type && m_clang_type_resolve_state < clang_type_resolve_state) 532 { 533 m_clang_type_resolve_state = eResolveStateFull; 534 if (!ClangASTType::IsDefined (m_clang_type)) 535 { 536 // We have a forward declaration, we need to resolve it to a complete 537 // definition. 538 m_symbol_file->ResolveClangOpaqueTypeDefinition (m_clang_type); 539 } 540 } 541 542 // If we have an encoding type, then we need to make sure it is 543 // resolved appropriately. 544 if (m_encoding_uid != LLDB_INVALID_UID) 545 { 546 if (encoding_type == NULL) 547 encoding_type = GetEncodingType(); 548 if (encoding_type) 549 { 550 ResolveState encoding_clang_type_resolve_state = clang_type_resolve_state; 551 552 if (clang_type_resolve_state == eResolveStateLayout) 553 { 554 switch (m_encoding_uid_type) 555 { 556 case eEncodingIsPointerUID: 557 case eEncodingIsLValueReferenceUID: 558 case eEncodingIsRValueReferenceUID: 559 encoding_clang_type_resolve_state = eResolveStateForward; 560 break; 561 default: 562 break; 563 } 564 } 565 encoding_type->ResolveClangType (encoding_clang_type_resolve_state); 566 } 567 } 568 return m_clang_type != NULL; 569 } 570 uint32_t 571 Type::GetEncodingMask () 572 { 573 uint32_t encoding_mask = 1u << m_encoding_uid_type; 574 Type *encoding_type = GetEncodingType(); 575 assert (encoding_type != this); 576 if (encoding_type) 577 encoding_mask |= encoding_type->GetEncodingMask (); 578 return encoding_mask; 579 } 580 581 clang_type_t 582 Type::GetClangFullType () 583 { 584 ResolveClangType(eResolveStateFull); 585 return m_clang_type; 586 } 587 588 clang_type_t 589 Type::GetClangLayoutType () 590 { 591 ResolveClangType(eResolveStateLayout); 592 return m_clang_type; 593 } 594 595 clang_type_t 596 Type::GetClangForwardType () 597 { 598 ResolveClangType (eResolveStateForward); 599 return m_clang_type; 600 } 601 602 clang::ASTContext * 603 Type::GetClangAST () 604 { 605 return GetClangASTContext().getASTContext(); 606 } 607 608 ClangASTContext & 609 Type::GetClangASTContext () 610 { 611 return m_symbol_file->GetClangASTContext(); 612 } 613 614 int 615 Type::Compare(const Type &a, const Type &b) 616 { 617 // Just compare the UID values for now... 618 lldb::user_id_t a_uid = a.GetID(); 619 lldb::user_id_t b_uid = b.GetID(); 620 if (a_uid < b_uid) 621 return -1; 622 if (a_uid > b_uid) 623 return 1; 624 return 0; 625 // if (a.getQualType() == b.getQualType()) 626 // return 0; 627 } 628 629 630 void * 631 Type::CreateClangPointerType (Type *type) 632 { 633 assert(type); 634 return GetClangASTContext().CreatePointerType(type->GetClangForwardType()); 635 } 636 637 void * 638 Type::CreateClangTypedefType (Type *typedef_type, Type *base_type) 639 { 640 assert(typedef_type && base_type); 641 return GetClangASTContext().CreateTypedefType (typedef_type->GetName().AsCString(), 642 base_type->GetClangForwardType(), 643 typedef_type->GetSymbolFile()->GetClangDeclContextContainingTypeUID(typedef_type->GetID())); 644 } 645 646 void * 647 Type::CreateClangLValueReferenceType (Type *type) 648 { 649 assert(type); 650 return GetClangASTContext().CreateLValueReferenceType(type->GetClangForwardType()); 651 } 652 653 void * 654 Type::CreateClangRValueReferenceType (Type *type) 655 { 656 assert(type); 657 return GetClangASTContext().CreateRValueReferenceType (type->GetClangForwardType()); 658 } 659 660 661 TypeAndOrName::TypeAndOrName () : m_type_sp(), m_type_name() 662 { 663 664 } 665 666 TypeAndOrName::TypeAndOrName (TypeSP &in_type_sp) : m_type_sp(in_type_sp) 667 { 668 if (in_type_sp) 669 m_type_name = in_type_sp->GetName(); 670 } 671 672 TypeAndOrName::TypeAndOrName (const char *in_type_str) : m_type_name(in_type_str) 673 { 674 } 675 676 TypeAndOrName::TypeAndOrName (const TypeAndOrName &rhs) : m_type_sp (rhs.m_type_sp), m_type_name (rhs.m_type_name) 677 { 678 679 } 680 681 TypeAndOrName::TypeAndOrName (ConstString &in_type_const_string) : m_type_name (in_type_const_string) 682 { 683 } 684 685 TypeAndOrName & 686 TypeAndOrName::operator= (const TypeAndOrName &rhs) 687 { 688 if (this != &rhs) 689 { 690 m_type_name = rhs.m_type_name; 691 m_type_sp = rhs.m_type_sp; 692 } 693 return *this; 694 } 695 696 ConstString 697 TypeAndOrName::GetName () const 698 { 699 if (m_type_sp) 700 return m_type_sp->GetName(); 701 else 702 return m_type_name; 703 } 704 705 void 706 TypeAndOrName::SetName (ConstString &type_name_const_str) 707 { 708 m_type_name = type_name_const_str; 709 } 710 711 void 712 TypeAndOrName::SetName (const char *type_name_str) 713 { 714 m_type_name.SetCString (type_name_str); 715 } 716 717 void 718 TypeAndOrName::SetTypeSP (lldb::TypeSP type_sp) 719 { 720 m_type_sp = type_sp; 721 if (type_sp) 722 m_type_name = type_sp->GetName(); 723 } 724 725 bool 726 TypeAndOrName::IsEmpty() 727 { 728 if (m_type_name || m_type_sp) 729 return false; 730 else 731 return true; 732 } 733 734 TypeImpl::TypeImpl(const lldb_private::ClangASTType& clang_ast_type) : 735 m_clang_ast_type(clang_ast_type.GetASTContext(), clang_ast_type.GetOpaqueQualType()), 736 m_type_sp() 737 {} 738 739 TypeImpl::TypeImpl(const lldb::TypeSP& type) : 740 m_clang_ast_type(type->GetClangAST(), type->GetClangFullType()), 741 m_type_sp(type) 742 { 743 } 744 745 TypeImpl& 746 TypeImpl::operator = (const TypeImpl& rhs) 747 { 748 if (*this != rhs) 749 { 750 m_clang_ast_type = rhs.m_clang_ast_type; 751 m_type_sp = rhs.m_type_sp; 752 } 753 return *this; 754 } 755 756 clang::ASTContext* 757 TypeImpl::GetASTContext() 758 { 759 if (!IsValid()) 760 return NULL; 761 762 return m_clang_ast_type.GetASTContext(); 763 } 764 765 lldb::clang_type_t 766 TypeImpl::GetOpaqueQualType() 767 { 768 if (!IsValid()) 769 return NULL; 770 771 return m_clang_ast_type.GetOpaqueQualType(); 772 } 773