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