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: ", 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 Target *target = NULL; 361 if (exe_ctx) 362 target = exe_ctx->GetTargetPtr(); 363 if (target) 364 data.SetByteOrder (target->GetArchitecture().GetByteOrder()); 365 if (ReadFromMemory (exe_ctx, address, address_type, data)) 366 { 367 DumpValue(exe_ctx, s, data, 0, show_types, show_summary, verbose); 368 return true; 369 } 370 } 371 return false; 372 } 373 374 375 bool 376 Type::ReadFromMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data) 377 { 378 if (address_type == eAddressTypeFile) 379 { 380 // Can't convert a file address to anything valid without more 381 // context (which Module it came from) 382 return false; 383 } 384 385 const uint32_t byte_size = GetByteSize(); 386 if (data.GetByteSize() < byte_size) 387 { 388 lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0')); 389 data.SetData(data_sp); 390 } 391 392 uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size); 393 if (dst != NULL) 394 { 395 if (address_type == eAddressTypeHost) 396 { 397 // The address is an address in this process, so just copy it 398 memcpy (dst, (uint8_t*)NULL + addr, byte_size); 399 return true; 400 } 401 else 402 { 403 if (exe_ctx) 404 { 405 Process *process = exe_ctx->GetProcessPtr(); 406 if (process) 407 { 408 Error error; 409 return exe_ctx->GetProcessPtr()->ReadMemory(addr, dst, byte_size, error) == byte_size; 410 } 411 } 412 } 413 } 414 return false; 415 } 416 417 418 bool 419 Type::WriteToMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data) 420 { 421 return false; 422 } 423 424 425 TypeList* 426 Type::GetTypeList() 427 { 428 return GetSymbolFile()->GetTypeList(); 429 } 430 431 const Declaration & 432 Type::GetDeclaration () const 433 { 434 return m_decl; 435 } 436 437 bool 438 Type::ResolveClangType (ResolveState clang_type_resolve_state) 439 { 440 Type *encoding_type = NULL; 441 if (m_clang_type == NULL) 442 { 443 encoding_type = GetEncodingType(); 444 if (encoding_type) 445 { 446 switch (m_encoding_uid_type) 447 { 448 case eEncodingIsUID: 449 if (encoding_type->ResolveClangType(clang_type_resolve_state)) 450 { 451 m_clang_type = encoding_type->m_clang_type; 452 m_clang_type_resolve_state = encoding_type->m_clang_type_resolve_state; 453 } 454 break; 455 456 case eEncodingIsConstUID: 457 m_clang_type = ClangASTContext::AddConstModifier (encoding_type->GetClangForwardType()); 458 break; 459 460 case eEncodingIsRestrictUID: 461 m_clang_type = ClangASTContext::AddRestrictModifier (encoding_type->GetClangForwardType()); 462 break; 463 464 case eEncodingIsVolatileUID: 465 m_clang_type = ClangASTContext::AddVolatileModifier (encoding_type->GetClangForwardType()); 466 break; 467 468 case eEncodingIsTypedefUID: 469 m_clang_type = CreateClangTypedefType (this, encoding_type); 470 // Clear the name so it can get fully qualified in case the 471 // typedef is in a namespace. 472 m_name.Clear(); 473 break; 474 475 case eEncodingIsPointerUID: 476 m_clang_type = CreateClangPointerType (encoding_type); 477 break; 478 479 case eEncodingIsLValueReferenceUID: 480 m_clang_type = CreateClangLValueReferenceType (encoding_type); 481 break; 482 483 case eEncodingIsRValueReferenceUID: 484 m_clang_type = CreateClangRValueReferenceType (encoding_type); 485 break; 486 487 default: 488 assert(!"Unhandled encoding_data_type."); 489 break; 490 } 491 } 492 else 493 { 494 // We have no encoding type, return void? 495 clang_type_t void_clang_type = GetClangASTContext().GetBuiltInType_void(); 496 switch (m_encoding_uid_type) 497 { 498 case eEncodingIsUID: 499 m_clang_type = void_clang_type; 500 break; 501 502 case eEncodingIsConstUID: 503 m_clang_type = ClangASTContext::AddConstModifier (void_clang_type); 504 break; 505 506 case eEncodingIsRestrictUID: 507 m_clang_type = ClangASTContext::AddRestrictModifier (void_clang_type); 508 break; 509 510 case eEncodingIsVolatileUID: 511 m_clang_type = ClangASTContext::AddVolatileModifier (void_clang_type); 512 break; 513 514 case eEncodingIsTypedefUID: 515 m_clang_type = GetClangASTContext().CreateTypedefType (m_name.AsCString(), void_clang_type, NULL); 516 break; 517 518 case eEncodingIsPointerUID: 519 m_clang_type = GetClangASTContext().CreatePointerType (void_clang_type); 520 break; 521 522 case eEncodingIsLValueReferenceUID: 523 m_clang_type = GetClangASTContext().CreateLValueReferenceType (void_clang_type); 524 break; 525 526 case eEncodingIsRValueReferenceUID: 527 m_clang_type = GetClangASTContext().CreateRValueReferenceType (void_clang_type); 528 break; 529 530 default: 531 assert(!"Unhandled encoding_data_type."); 532 break; 533 } 534 } 535 } 536 537 // Check if we have a forward reference to a class/struct/union/enum? 538 if (m_clang_type && m_clang_type_resolve_state < clang_type_resolve_state) 539 { 540 m_clang_type_resolve_state = eResolveStateFull; 541 if (!ClangASTType::IsDefined (m_clang_type)) 542 { 543 // We have a forward declaration, we need to resolve it to a complete 544 // definition. 545 m_symbol_file->ResolveClangOpaqueTypeDefinition (m_clang_type); 546 } 547 } 548 549 // If we have an encoding type, then we need to make sure it is 550 // resolved appropriately. 551 if (m_encoding_uid != LLDB_INVALID_UID) 552 { 553 if (encoding_type == NULL) 554 encoding_type = GetEncodingType(); 555 if (encoding_type) 556 { 557 ResolveState encoding_clang_type_resolve_state = clang_type_resolve_state; 558 559 if (clang_type_resolve_state == eResolveStateLayout) 560 { 561 switch (m_encoding_uid_type) 562 { 563 case eEncodingIsPointerUID: 564 case eEncodingIsLValueReferenceUID: 565 case eEncodingIsRValueReferenceUID: 566 encoding_clang_type_resolve_state = eResolveStateForward; 567 break; 568 default: 569 break; 570 } 571 } 572 encoding_type->ResolveClangType (encoding_clang_type_resolve_state); 573 } 574 } 575 return m_clang_type != NULL; 576 } 577 uint32_t 578 Type::GetEncodingMask () 579 { 580 uint32_t encoding_mask = 1u << m_encoding_uid_type; 581 Type *encoding_type = GetEncodingType(); 582 assert (encoding_type != this); 583 if (encoding_type) 584 encoding_mask |= encoding_type->GetEncodingMask (); 585 return encoding_mask; 586 } 587 588 clang_type_t 589 Type::GetClangFullType () 590 { 591 ResolveClangType(eResolveStateFull); 592 return m_clang_type; 593 } 594 595 clang_type_t 596 Type::GetClangLayoutType () 597 { 598 ResolveClangType(eResolveStateLayout); 599 return m_clang_type; 600 } 601 602 clang_type_t 603 Type::GetClangForwardType () 604 { 605 ResolveClangType (eResolveStateForward); 606 return m_clang_type; 607 } 608 609 clang::ASTContext * 610 Type::GetClangAST () 611 { 612 return GetClangASTContext().getASTContext(); 613 } 614 615 ClangASTContext & 616 Type::GetClangASTContext () 617 { 618 return m_symbol_file->GetClangASTContext(); 619 } 620 621 int 622 Type::Compare(const Type &a, const Type &b) 623 { 624 // Just compare the UID values for now... 625 lldb::user_id_t a_uid = a.GetID(); 626 lldb::user_id_t b_uid = b.GetID(); 627 if (a_uid < b_uid) 628 return -1; 629 if (a_uid > b_uid) 630 return 1; 631 return 0; 632 // if (a.getQualType() == b.getQualType()) 633 // return 0; 634 } 635 636 637 void * 638 Type::CreateClangPointerType (Type *type) 639 { 640 assert(type); 641 return GetClangASTContext().CreatePointerType(type->GetClangForwardType()); 642 } 643 644 void * 645 Type::CreateClangTypedefType (Type *typedef_type, Type *base_type) 646 { 647 assert(typedef_type && base_type); 648 return GetClangASTContext().CreateTypedefType (typedef_type->GetName().AsCString(), 649 base_type->GetClangForwardType(), 650 typedef_type->GetSymbolFile()->GetClangDeclContextContainingTypeUID(typedef_type->GetID())); 651 } 652 653 void * 654 Type::CreateClangLValueReferenceType (Type *type) 655 { 656 assert(type); 657 return GetClangASTContext().CreateLValueReferenceType(type->GetClangForwardType()); 658 } 659 660 void * 661 Type::CreateClangRValueReferenceType (Type *type) 662 { 663 assert(type); 664 return GetClangASTContext().CreateRValueReferenceType (type->GetClangForwardType()); 665 } 666 667 668 TypeAndOrName::TypeAndOrName () : m_type_sp(), m_type_name() 669 { 670 671 } 672 673 TypeAndOrName::TypeAndOrName (TypeSP &in_type_sp) : m_type_sp(in_type_sp) 674 { 675 if (in_type_sp) 676 m_type_name = in_type_sp->GetName(); 677 } 678 679 TypeAndOrName::TypeAndOrName (const char *in_type_str) : m_type_name(in_type_str) 680 { 681 } 682 683 TypeAndOrName::TypeAndOrName (const TypeAndOrName &rhs) : m_type_sp (rhs.m_type_sp), m_type_name (rhs.m_type_name) 684 { 685 686 } 687 688 TypeAndOrName::TypeAndOrName (ConstString &in_type_const_string) : m_type_name (in_type_const_string) 689 { 690 } 691 692 TypeAndOrName & 693 TypeAndOrName::operator= (const TypeAndOrName &rhs) 694 { 695 if (this != &rhs) 696 { 697 m_type_name = rhs.m_type_name; 698 m_type_sp = rhs.m_type_sp; 699 } 700 return *this; 701 } 702 703 ConstString 704 TypeAndOrName::GetName () const 705 { 706 if (m_type_sp) 707 return m_type_sp->GetName(); 708 else 709 return m_type_name; 710 } 711 712 void 713 TypeAndOrName::SetName (ConstString &type_name_const_str) 714 { 715 m_type_name = type_name_const_str; 716 } 717 718 void 719 TypeAndOrName::SetName (const char *type_name_str) 720 { 721 m_type_name.SetCString (type_name_str); 722 } 723 724 void 725 TypeAndOrName::SetTypeSP (lldb::TypeSP type_sp) 726 { 727 m_type_sp = type_sp; 728 if (type_sp) 729 m_type_name = type_sp->GetName(); 730 } 731 732 bool 733 TypeAndOrName::IsEmpty() 734 { 735 if (m_type_name || m_type_sp) 736 return false; 737 else 738 return true; 739 } 740 741 TypeImpl::TypeImpl(const lldb_private::ClangASTType& clang_ast_type) : 742 m_clang_ast_type(clang_ast_type.GetASTContext(), clang_ast_type.GetOpaqueQualType()), 743 m_type_sp() 744 {} 745 746 TypeImpl::TypeImpl(const lldb::TypeSP& type) : 747 m_clang_ast_type(type->GetClangAST(), type->GetClangFullType()), 748 m_type_sp(type) 749 { 750 } 751 752 TypeImpl& 753 TypeImpl::operator = (const TypeImpl& rhs) 754 { 755 if (*this != rhs) 756 { 757 m_clang_ast_type = rhs.m_clang_ast_type; 758 m_type_sp = rhs.m_type_sp; 759 } 760 return *this; 761 } 762 763 clang::ASTContext* 764 TypeImpl::GetASTContext() 765 { 766 if (!IsValid()) 767 return NULL; 768 769 return m_clang_ast_type.GetASTContext(); 770 } 771 772 lldb::clang_type_t 773 TypeImpl::GetOpaqueQualType() 774 { 775 if (!IsValid()) 776 return NULL; 777 778 return m_clang_ast_type.GetOpaqueQualType(); 779 } 780