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