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