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 { 201 std::string type_name = ClangASTContext::GetTypeName (m_clang_type); 202 if (!type_name.empty()) 203 m_name.SetCString (type_name.c_str()); 204 } 205 } 206 return m_name; 207 } 208 209 void 210 Type::DumpTypeName(Stream *s) 211 { 212 GetName().Dump(s, "<invalid-type-name>"); 213 } 214 215 216 void 217 Type::DumpValue 218 ( 219 ExecutionContext *exe_ctx, 220 Stream *s, 221 const DataExtractor &data, 222 uint32_t data_byte_offset, 223 bool show_types, 224 bool show_summary, 225 bool verbose, 226 lldb::Format format 227 ) 228 { 229 if (ResolveClangType(eResolveStateForward)) 230 { 231 if (show_types) 232 { 233 s->PutChar('('); 234 if (verbose) 235 s->Printf("Type{0x%8.8x} ", GetID()); 236 DumpTypeName (s); 237 s->PutCString(") "); 238 } 239 240 ClangASTType::DumpValue (GetClangAST (), 241 m_clang_type, 242 exe_ctx, 243 s, 244 format == lldb::eFormatDefault ? GetFormat() : format, 245 data, 246 data_byte_offset, 247 GetByteSize(), 248 0, // Bitfield bit size 249 0, // Bitfield bit offset 250 show_types, 251 show_summary, 252 verbose, 253 0); 254 } 255 } 256 257 Type * 258 Type::GetEncodingType () 259 { 260 if (m_encoding_type == NULL && m_encoding_uid != LLDB_INVALID_UID) 261 m_encoding_type = m_symbol_file->ResolveTypeUID(m_encoding_uid); 262 return m_encoding_type; 263 } 264 265 266 267 uint32_t 268 Type::GetByteSize() 269 { 270 if (m_byte_size == 0) 271 { 272 switch (m_encoding_uid_type) 273 { 274 case eEncodingInvalid: 275 case eEncodingIsSyntheticUID: 276 break; 277 case eEncodingIsUID: 278 case eEncodingIsConstUID: 279 case eEncodingIsRestrictUID: 280 case eEncodingIsVolatileUID: 281 case eEncodingIsTypedefUID: 282 { 283 Type *encoding_type = GetEncodingType (); 284 if (encoding_type) 285 m_byte_size = encoding_type->GetByteSize(); 286 if (m_byte_size == 0) 287 { 288 uint32_t bit_width = ClangASTType::GetClangTypeBitWidth (GetClangAST(), GetClangLayoutType()); 289 m_byte_size = (bit_width + 7 ) / 8; 290 } 291 } 292 break; 293 294 // If we are a pointer or reference, then this is just a pointer size; 295 case eEncodingIsPointerUID: 296 case eEncodingIsLValueReferenceUID: 297 case eEncodingIsRValueReferenceUID: 298 m_byte_size = m_symbol_file->GetClangASTContext().GetPointerBitSize() / 8; 299 break; 300 } 301 } 302 return m_byte_size; 303 } 304 305 306 uint32_t 307 Type::GetNumChildren (bool omit_empty_base_classes) 308 { 309 if (ResolveClangType(eResolveStateForward)) 310 { 311 return ClangASTContext::GetNumChildren (m_symbol_file->GetClangASTContext().getASTContext(), 312 m_clang_type, 313 omit_empty_base_classes); 314 } 315 return 0; 316 } 317 318 bool 319 Type::IsAggregateType () 320 { 321 if (ResolveClangType(eResolveStateForward)) 322 return ClangASTContext::IsAggregateType (m_clang_type); 323 return false; 324 } 325 326 lldb::Format 327 Type::GetFormat () 328 { 329 // Make sure we resolve our type if it already hasn't been. 330 if (!ResolveClangType(eResolveStateForward)) 331 return lldb::eFormatInvalid; 332 return ClangASTType::GetFormat (m_clang_type); 333 } 334 335 336 337 lldb::Encoding 338 Type::GetEncoding (uint32_t &count) 339 { 340 // Make sure we resolve our type if it already hasn't been. 341 if (!ResolveClangType(eResolveStateForward)) 342 return lldb::eEncodingInvalid; 343 344 return ClangASTType::GetEncoding (m_clang_type, count); 345 } 346 347 348 349 bool 350 Type::DumpValueInMemory 351 ( 352 ExecutionContext *exe_ctx, 353 Stream *s, 354 lldb::addr_t address, 355 AddressType address_type, 356 bool show_types, 357 bool show_summary, 358 bool verbose 359 ) 360 { 361 if (address != LLDB_INVALID_ADDRESS) 362 { 363 DataExtractor data; 364 if (exe_ctx->target) 365 data.SetByteOrder (exe_ctx->target->GetArchitecture().GetByteOrder()); 366 if (ReadFromMemory (exe_ctx, address, address_type, data)) 367 { 368 DumpValue(exe_ctx, s, data, 0, show_types, show_summary, verbose); 369 return true; 370 } 371 } 372 return false; 373 } 374 375 376 bool 377 Type::ReadFromMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data) 378 { 379 if (address_type == eAddressTypeFile) 380 { 381 // Can't convert a file address to anything valid without more 382 // context (which Module it came from) 383 return false; 384 } 385 386 const uint32_t byte_size = GetByteSize(); 387 if (data.GetByteSize() < byte_size) 388 { 389 lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0')); 390 data.SetData(data_sp); 391 } 392 393 uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size); 394 if (dst != NULL) 395 { 396 if (address_type == eAddressTypeHost) 397 { 398 // The address is an address in this process, so just copy it 399 memcpy (dst, (uint8_t*)NULL + addr, byte_size); 400 return true; 401 } 402 else 403 { 404 if (exe_ctx && exe_ctx->process) 405 { 406 Error error; 407 return exe_ctx->process->ReadMemory(addr, dst, byte_size, error) == byte_size; 408 } 409 } 410 } 411 return false; 412 } 413 414 415 bool 416 Type::WriteToMemory (ExecutionContext *exe_ctx, lldb::addr_t addr, AddressType address_type, DataExtractor &data) 417 { 418 return false; 419 } 420 421 422 TypeList* 423 Type::GetTypeList() 424 { 425 return GetSymbolFile()->GetTypeList(); 426 } 427 428 const Declaration & 429 Type::GetDeclaration () const 430 { 431 return m_decl; 432 } 433 434 bool 435 Type::ResolveClangType (ResolveState clang_type_resolve_state) 436 { 437 Type *encoding_type = NULL; 438 if (m_clang_type == NULL) 439 { 440 encoding_type = GetEncodingType(); 441 if (encoding_type) 442 { 443 switch (m_encoding_uid_type) 444 { 445 case eEncodingIsUID: 446 if (encoding_type->ResolveClangType(clang_type_resolve_state)) 447 { 448 m_clang_type = encoding_type->m_clang_type; 449 m_clang_type_resolve_state = encoding_type->m_clang_type_resolve_state; 450 } 451 break; 452 453 case eEncodingIsConstUID: 454 m_clang_type = ClangASTContext::AddConstModifier (encoding_type->GetClangForwardType()); 455 break; 456 457 case eEncodingIsRestrictUID: 458 m_clang_type = ClangASTContext::AddRestrictModifier (encoding_type->GetClangForwardType()); 459 break; 460 461 case eEncodingIsVolatileUID: 462 m_clang_type = ClangASTContext::AddVolatileModifier (encoding_type->GetClangForwardType()); 463 break; 464 465 case eEncodingIsTypedefUID: 466 m_clang_type = CreateClangTypedefType (this, encoding_type); 467 // Clear the name so it can get fully qualified in case the 468 // typedef is in a namespace. 469 m_name.Clear(); 470 break; 471 472 case eEncodingIsPointerUID: 473 m_clang_type = CreateClangPointerType (encoding_type); 474 break; 475 476 case eEncodingIsLValueReferenceUID: 477 m_clang_type = CreateClangLValueReferenceType (encoding_type); 478 break; 479 480 case eEncodingIsRValueReferenceUID: 481 m_clang_type = CreateClangRValueReferenceType (encoding_type); 482 break; 483 484 default: 485 assert(!"Unhandled encoding_data_type."); 486 break; 487 } 488 } 489 else 490 { 491 // We have no encoding type, return void? 492 clang_type_t void_clang_type = GetClangASTContext().GetBuiltInType_void(); 493 switch (m_encoding_uid_type) 494 { 495 case eEncodingIsUID: 496 m_clang_type = void_clang_type; 497 break; 498 499 case eEncodingIsConstUID: 500 m_clang_type = ClangASTContext::AddConstModifier (void_clang_type); 501 break; 502 503 case eEncodingIsRestrictUID: 504 m_clang_type = ClangASTContext::AddRestrictModifier (void_clang_type); 505 break; 506 507 case eEncodingIsVolatileUID: 508 m_clang_type = ClangASTContext::AddVolatileModifier (void_clang_type); 509 break; 510 511 case eEncodingIsTypedefUID: 512 m_clang_type = GetClangASTContext().CreateTypedefType (m_name.AsCString(), void_clang_type, NULL); 513 break; 514 515 case eEncodingIsPointerUID: 516 m_clang_type = GetClangASTContext().CreatePointerType (void_clang_type); 517 break; 518 519 case eEncodingIsLValueReferenceUID: 520 m_clang_type = GetClangASTContext().CreateLValueReferenceType (void_clang_type); 521 break; 522 523 case eEncodingIsRValueReferenceUID: 524 m_clang_type = GetClangASTContext().CreateRValueReferenceType (void_clang_type); 525 break; 526 527 default: 528 assert(!"Unhandled encoding_data_type."); 529 break; 530 } 531 } 532 } 533 534 // Check if we have a forward reference to a class/struct/union/enum? 535 if (m_clang_type && m_clang_type_resolve_state < clang_type_resolve_state) 536 { 537 m_clang_type_resolve_state = eResolveStateFull; 538 if (!ClangASTType::IsDefined (m_clang_type)) 539 { 540 // We have a forward declaration, we need to resolve it to a complete 541 // definition. 542 m_symbol_file->ResolveClangOpaqueTypeDefinition (m_clang_type); 543 } 544 } 545 546 // If we have an encoding type, then we need to make sure it is 547 // resolved appropriately. 548 if (m_encoding_uid != LLDB_INVALID_UID) 549 { 550 if (encoding_type == NULL) 551 encoding_type = GetEncodingType(); 552 if (encoding_type) 553 { 554 ResolveState encoding_clang_type_resolve_state = clang_type_resolve_state; 555 556 if (clang_type_resolve_state == eResolveStateLayout) 557 { 558 switch (m_encoding_uid_type) 559 { 560 case eEncodingIsPointerUID: 561 case eEncodingIsLValueReferenceUID: 562 case eEncodingIsRValueReferenceUID: 563 encoding_clang_type_resolve_state = eResolveStateForward; 564 break; 565 default: 566 break; 567 } 568 } 569 encoding_type->ResolveClangType (encoding_clang_type_resolve_state); 570 } 571 } 572 return m_clang_type != NULL; 573 } 574 uint32_t 575 Type::GetEncodingMask () 576 { 577 uint32_t encoding_mask = 1u << m_encoding_uid_type; 578 Type *encoding_type = GetEncodingType(); 579 assert (encoding_type != this); 580 if (encoding_type) 581 encoding_mask |= encoding_type->GetEncodingMask (); 582 return encoding_mask; 583 } 584 585 clang_type_t 586 Type::GetClangFullType () 587 { 588 ResolveClangType(eResolveStateFull); 589 return m_clang_type; 590 } 591 592 clang_type_t 593 Type::GetClangLayoutType () 594 { 595 ResolveClangType(eResolveStateLayout); 596 return m_clang_type; 597 } 598 599 clang_type_t 600 Type::GetClangForwardType () 601 { 602 ResolveClangType (eResolveStateForward); 603 return m_clang_type; 604 } 605 606 clang::ASTContext * 607 Type::GetClangAST () 608 { 609 return GetClangASTContext().getASTContext(); 610 } 611 612 ClangASTContext & 613 Type::GetClangASTContext () 614 { 615 return m_symbol_file->GetClangASTContext(); 616 } 617 618 int 619 Type::Compare(const Type &a, const Type &b) 620 { 621 // Just compare the UID values for now... 622 lldb::user_id_t a_uid = a.GetID(); 623 lldb::user_id_t b_uid = b.GetID(); 624 if (a_uid < b_uid) 625 return -1; 626 if (a_uid > b_uid) 627 return 1; 628 return 0; 629 // if (a.getQualType() == b.getQualType()) 630 // return 0; 631 } 632 633 634 void * 635 Type::CreateClangPointerType (Type *type) 636 { 637 assert(type); 638 return GetClangASTContext().CreatePointerType(type->GetClangForwardType()); 639 } 640 641 void * 642 Type::CreateClangTypedefType (Type *typedef_type, Type *base_type) 643 { 644 assert(typedef_type && base_type); 645 return GetClangASTContext().CreateTypedefType (typedef_type->GetName().AsCString(), 646 base_type->GetClangForwardType(), 647 typedef_type->GetSymbolFile()->GetClangDeclContextForTypeUID(typedef_type->GetID())); 648 } 649 650 void * 651 Type::CreateClangLValueReferenceType (Type *type) 652 { 653 assert(type); 654 return GetClangASTContext().CreateLValueReferenceType(type->GetClangForwardType()); 655 } 656 657 void * 658 Type::CreateClangRValueReferenceType (Type *type) 659 { 660 assert(type); 661 return GetClangASTContext().CreateRValueReferenceType (type->GetClangForwardType()); 662 } 663 664 665 TypeAndOrName::TypeAndOrName () : m_type_sp(), m_type_name() 666 { 667 668 } 669 670 TypeAndOrName::TypeAndOrName (TypeSP &in_type_sp) : m_type_sp(in_type_sp) 671 { 672 if (in_type_sp) 673 m_type_name = in_type_sp->GetName(); 674 } 675 676 TypeAndOrName::TypeAndOrName (const char *in_type_str) : m_type_name(in_type_str) 677 { 678 } 679 680 TypeAndOrName::TypeAndOrName (const TypeAndOrName &rhs) : m_type_sp (rhs.m_type_sp), m_type_name (rhs.m_type_name) 681 { 682 683 } 684 685 TypeAndOrName::TypeAndOrName (ConstString &in_type_const_string) : m_type_name (in_type_const_string) 686 { 687 } 688 689 TypeAndOrName & 690 TypeAndOrName::operator= (const TypeAndOrName &rhs) 691 { 692 if (this != &rhs) 693 { 694 m_type_name = rhs.m_type_name; 695 m_type_sp = rhs.m_type_sp; 696 } 697 return *this; 698 } 699 700 ConstString 701 TypeAndOrName::GetName () const 702 { 703 if (m_type_sp) 704 return m_type_sp->GetName(); 705 else 706 return m_type_name; 707 } 708 709 void 710 TypeAndOrName::SetName (ConstString &type_name_const_str) 711 { 712 m_type_name = type_name_const_str; 713 } 714 715 void 716 TypeAndOrName::SetName (const char *type_name_str) 717 { 718 m_type_name.SetCString (type_name_str); 719 } 720 721 void 722 TypeAndOrName::SetTypeSP (lldb::TypeSP type_sp) 723 { 724 m_type_sp = type_sp; 725 if (type_sp) 726 m_type_name = type_sp->GetName(); 727 } 728 729 bool 730 TypeAndOrName::IsEmpty() 731 { 732 if (m_type_name || m_type_sp) 733 return false; 734 else 735 return true; 736 } 737