1 //===-- Type.cpp ------------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include <stdio.h> 10 11 #include "lldb/Core/Module.h" 12 #include "lldb/Utility/DataBufferHeap.h" 13 #include "lldb/Utility/DataExtractor.h" 14 #include "lldb/Utility/Scalar.h" 15 #include "lldb/Utility/StreamString.h" 16 17 #include "lldb/Symbol/CompilerType.h" 18 #include "lldb/Symbol/ObjectFile.h" 19 #include "lldb/Symbol/SymbolContextScope.h" 20 #include "lldb/Symbol/SymbolFile.h" 21 #include "lldb/Symbol/SymbolVendor.h" 22 #include "lldb/Symbol/Type.h" 23 #include "lldb/Symbol/TypeList.h" 24 #include "lldb/Symbol/TypeSystem.h" 25 26 #include "lldb/Target/ExecutionContext.h" 27 #include "lldb/Target/Process.h" 28 #include "lldb/Target/Target.h" 29 30 #include "llvm/ADT/StringRef.h" 31 32 #include "clang/AST/Decl.h" 33 #include "clang/AST/DeclObjC.h" 34 35 using namespace lldb; 36 using namespace lldb_private; 37 38 void CompilerContext::Dump() const { 39 switch (type) { 40 case CompilerContextKind::Invalid: 41 printf("Invalid"); 42 break; 43 case CompilerContextKind::TranslationUnit: 44 printf("TranslationUnit"); 45 break; 46 case CompilerContextKind::Module: 47 printf("Module"); 48 break; 49 case CompilerContextKind::Namespace: 50 printf("Namespace"); 51 break; 52 case CompilerContextKind::Class: 53 printf("Class"); 54 break; 55 case CompilerContextKind::Structure: 56 printf("Structure"); 57 break; 58 case CompilerContextKind::Union: 59 printf("Union"); 60 break; 61 case CompilerContextKind::Function: 62 printf("Function"); 63 break; 64 case CompilerContextKind::Variable: 65 printf("Variable"); 66 break; 67 case CompilerContextKind::Enumeration: 68 printf("Enumeration"); 69 break; 70 case CompilerContextKind::Typedef: 71 printf("Typedef"); 72 break; 73 } 74 printf("(\"%s\")\n", name.GetCString()); 75 } 76 77 class TypeAppendVisitor { 78 public: 79 TypeAppendVisitor(TypeListImpl &type_list) : m_type_list(type_list) {} 80 81 bool operator()(const lldb::TypeSP &type) { 82 m_type_list.Append(TypeImplSP(new TypeImpl(type))); 83 return true; 84 } 85 86 private: 87 TypeListImpl &m_type_list; 88 }; 89 90 void TypeListImpl::Append(const lldb_private::TypeList &type_list) { 91 TypeAppendVisitor cb(*this); 92 type_list.ForEach(cb); 93 } 94 95 SymbolFileType::SymbolFileType(SymbolFile &symbol_file, 96 const lldb::TypeSP &type_sp) 97 : UserID(type_sp ? type_sp->GetID() : LLDB_INVALID_UID), 98 m_symbol_file(symbol_file), m_type_sp(type_sp) {} 99 100 Type *SymbolFileType::GetType() { 101 if (!m_type_sp) { 102 Type *resolved_type = m_symbol_file.ResolveTypeUID(GetID()); 103 if (resolved_type) 104 m_type_sp = resolved_type->shared_from_this(); 105 } 106 return m_type_sp.get(); 107 } 108 109 Type::Type(lldb::user_id_t uid, SymbolFile *symbol_file, 110 ConstString name, llvm::Optional<uint64_t> byte_size, 111 SymbolContextScope *context, user_id_t encoding_uid, 112 EncodingDataType encoding_uid_type, const Declaration &decl, 113 const CompilerType &compiler_type, 114 ResolveState compiler_type_resolve_state) 115 : std::enable_shared_from_this<Type>(), UserID(uid), m_name(name), 116 m_symbol_file(symbol_file), m_context(context), m_encoding_type(nullptr), 117 m_encoding_uid(encoding_uid), m_encoding_uid_type(encoding_uid_type), 118 m_decl(decl), m_compiler_type(compiler_type) { 119 if (byte_size) { 120 m_byte_size = *byte_size; 121 m_byte_size_has_value = true; 122 } else { 123 m_byte_size = 0; 124 m_byte_size_has_value = false; 125 } 126 m_flags.compiler_type_resolve_state = 127 (compiler_type ? compiler_type_resolve_state : eResolveStateUnresolved); 128 m_flags.is_complete_objc_class = false; 129 } 130 131 Type::Type() 132 : std::enable_shared_from_this<Type>(), UserID(0), m_name("<INVALID TYPE>"), 133 m_symbol_file(nullptr), m_context(nullptr), m_encoding_type(nullptr), 134 m_encoding_uid(LLDB_INVALID_UID), m_encoding_uid_type(eEncodingInvalid), 135 m_byte_size(0), m_byte_size_has_value(false), m_decl(), 136 m_compiler_type() { 137 m_flags.compiler_type_resolve_state = eResolveStateUnresolved; 138 m_flags.is_complete_objc_class = false; 139 } 140 141 void Type::GetDescription(Stream *s, lldb::DescriptionLevel level, 142 bool show_name) { 143 *s << "id = " << (const UserID &)*this; 144 145 // Call the name accessor to make sure we resolve the type name 146 if (show_name) { 147 ConstString type_name = GetName(); 148 if (type_name) { 149 *s << ", name = \"" << type_name << '"'; 150 ConstString qualified_type_name(GetQualifiedName()); 151 if (qualified_type_name != type_name) { 152 *s << ", qualified = \"" << qualified_type_name << '"'; 153 } 154 } 155 } 156 157 // Call the get byte size accesor so we resolve our byte size 158 if (GetByteSize()) 159 s->Printf(", byte-size = %" PRIu64, m_byte_size); 160 bool show_fullpaths = (level == lldb::eDescriptionLevelVerbose); 161 m_decl.Dump(s, show_fullpaths); 162 163 if (m_compiler_type.IsValid()) { 164 *s << ", compiler_type = \""; 165 GetForwardCompilerType().DumpTypeDescription(s); 166 *s << '"'; 167 } else if (m_encoding_uid != LLDB_INVALID_UID) { 168 s->Printf(", type_uid = 0x%8.8" PRIx64, m_encoding_uid); 169 switch (m_encoding_uid_type) { 170 case eEncodingInvalid: 171 break; 172 case eEncodingIsUID: 173 s->PutCString(" (unresolved type)"); 174 break; 175 case eEncodingIsConstUID: 176 s->PutCString(" (unresolved const type)"); 177 break; 178 case eEncodingIsRestrictUID: 179 s->PutCString(" (unresolved restrict type)"); 180 break; 181 case eEncodingIsVolatileUID: 182 s->PutCString(" (unresolved volatile type)"); 183 break; 184 case eEncodingIsTypedefUID: 185 s->PutCString(" (unresolved typedef)"); 186 break; 187 case eEncodingIsPointerUID: 188 s->PutCString(" (unresolved pointer)"); 189 break; 190 case eEncodingIsLValueReferenceUID: 191 s->PutCString(" (unresolved L value reference)"); 192 break; 193 case eEncodingIsRValueReferenceUID: 194 s->PutCString(" (unresolved R value reference)"); 195 break; 196 case eEncodingIsSyntheticUID: 197 s->PutCString(" (synthetic type)"); 198 break; 199 } 200 } 201 } 202 203 void Type::Dump(Stream *s, bool show_context) { 204 s->Printf("%p: ", static_cast<void *>(this)); 205 s->Indent(); 206 *s << "Type" << static_cast<const UserID &>(*this) << ' '; 207 if (m_name) 208 *s << ", name = \"" << m_name << "\""; 209 210 if (m_byte_size_has_value) 211 s->Printf(", size = %" PRIu64, m_byte_size); 212 213 if (show_context && m_context != nullptr) { 214 s->PutCString(", context = ( "); 215 m_context->DumpSymbolContext(s); 216 s->PutCString(" )"); 217 } 218 219 bool show_fullpaths = false; 220 m_decl.Dump(s, show_fullpaths); 221 222 if (m_compiler_type.IsValid()) { 223 *s << ", compiler_type = " << m_compiler_type.GetOpaqueQualType() << ' '; 224 GetForwardCompilerType().DumpTypeDescription(s); 225 } else if (m_encoding_uid != LLDB_INVALID_UID) { 226 *s << ", type_data = " << (uint64_t)m_encoding_uid; 227 switch (m_encoding_uid_type) { 228 case eEncodingInvalid: 229 break; 230 case eEncodingIsUID: 231 s->PutCString(" (unresolved type)"); 232 break; 233 case eEncodingIsConstUID: 234 s->PutCString(" (unresolved const type)"); 235 break; 236 case eEncodingIsRestrictUID: 237 s->PutCString(" (unresolved restrict type)"); 238 break; 239 case eEncodingIsVolatileUID: 240 s->PutCString(" (unresolved volatile type)"); 241 break; 242 case eEncodingIsTypedefUID: 243 s->PutCString(" (unresolved typedef)"); 244 break; 245 case eEncodingIsPointerUID: 246 s->PutCString(" (unresolved pointer)"); 247 break; 248 case eEncodingIsLValueReferenceUID: 249 s->PutCString(" (unresolved L value reference)"); 250 break; 251 case eEncodingIsRValueReferenceUID: 252 s->PutCString(" (unresolved R value reference)"); 253 break; 254 case eEncodingIsSyntheticUID: 255 s->PutCString(" (synthetic type)"); 256 break; 257 } 258 } 259 260 // 261 // if (m_access) 262 // s->Printf(", access = %u", m_access); 263 s->EOL(); 264 } 265 266 ConstString Type::GetName() { 267 if (!m_name) 268 m_name = GetForwardCompilerType().GetConstTypeName(); 269 return m_name; 270 } 271 272 void Type::DumpTypeName(Stream *s) { GetName().Dump(s, "<invalid-type-name>"); } 273 274 void Type::DumpValue(ExecutionContext *exe_ctx, Stream *s, 275 const DataExtractor &data, uint32_t data_byte_offset, 276 bool show_types, bool show_summary, bool verbose, 277 lldb::Format format) { 278 if (ResolveClangType(eResolveStateForward)) { 279 if (show_types) { 280 s->PutChar('('); 281 if (verbose) 282 s->Printf("Type{0x%8.8" PRIx64 "} ", GetID()); 283 DumpTypeName(s); 284 s->PutCString(") "); 285 } 286 287 GetForwardCompilerType().DumpValue( 288 exe_ctx, s, format == lldb::eFormatDefault ? GetFormat() : format, data, 289 data_byte_offset, GetByteSize().getValueOr(0), 290 0, // Bitfield bit size 291 0, // Bitfield bit offset 292 show_types, show_summary, verbose, 0); 293 } 294 } 295 296 Type *Type::GetEncodingType() { 297 if (m_encoding_type == nullptr && m_encoding_uid != LLDB_INVALID_UID) 298 m_encoding_type = m_symbol_file->ResolveTypeUID(m_encoding_uid); 299 return m_encoding_type; 300 } 301 302 llvm::Optional<uint64_t> Type::GetByteSize() { 303 if (m_byte_size_has_value) 304 return m_byte_size; 305 306 switch (m_encoding_uid_type) { 307 case eEncodingInvalid: 308 case eEncodingIsSyntheticUID: 309 break; 310 case eEncodingIsUID: 311 case eEncodingIsConstUID: 312 case eEncodingIsRestrictUID: 313 case eEncodingIsVolatileUID: 314 case eEncodingIsTypedefUID: { 315 Type *encoding_type = GetEncodingType(); 316 if (encoding_type) 317 if (llvm::Optional<uint64_t> size = encoding_type->GetByteSize()) { 318 m_byte_size = *size; 319 m_byte_size_has_value = true; 320 return m_byte_size; 321 } 322 323 if (llvm::Optional<uint64_t> size = 324 GetLayoutCompilerType().GetByteSize(nullptr)) { 325 m_byte_size = *size; 326 m_byte_size_has_value = true; 327 return m_byte_size; 328 } 329 } break; 330 331 // If we are a pointer or reference, then this is just a pointer size; 332 case eEncodingIsPointerUID: 333 case eEncodingIsLValueReferenceUID: 334 case eEncodingIsRValueReferenceUID: { 335 if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) { 336 m_byte_size = arch.GetAddressByteSize(); 337 m_byte_size_has_value = true; 338 } 339 } break; 340 } 341 return {}; 342 } 343 344 uint32_t Type::GetNumChildren(bool omit_empty_base_classes) { 345 return GetForwardCompilerType().GetNumChildren(omit_empty_base_classes, nullptr); 346 } 347 348 bool Type::IsAggregateType() { 349 return GetForwardCompilerType().IsAggregateType(); 350 } 351 352 lldb::TypeSP Type::GetTypedefType() { 353 lldb::TypeSP type_sp; 354 if (IsTypedef()) { 355 Type *typedef_type = m_symbol_file->ResolveTypeUID(m_encoding_uid); 356 if (typedef_type) 357 type_sp = typedef_type->shared_from_this(); 358 } 359 return type_sp; 360 } 361 362 lldb::Format Type::GetFormat() { return GetForwardCompilerType().GetFormat(); } 363 364 lldb::Encoding Type::GetEncoding(uint64_t &count) { 365 // Make sure we resolve our type if it already hasn't been. 366 return GetForwardCompilerType().GetEncoding(count); 367 } 368 369 bool Type::DumpValueInMemory(ExecutionContext *exe_ctx, Stream *s, 370 lldb::addr_t address, AddressType address_type, 371 bool show_types, bool show_summary, bool verbose) { 372 if (address != LLDB_INVALID_ADDRESS) { 373 DataExtractor data; 374 Target *target = nullptr; 375 if (exe_ctx) 376 target = exe_ctx->GetTargetPtr(); 377 if (target) 378 data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 379 if (ReadFromMemory(exe_ctx, address, address_type, data)) { 380 DumpValue(exe_ctx, s, data, 0, show_types, show_summary, verbose); 381 return true; 382 } 383 } 384 return false; 385 } 386 387 bool Type::ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t addr, 388 AddressType address_type, DataExtractor &data) { 389 if (address_type == eAddressTypeFile) { 390 // Can't convert a file address to anything valid without more context 391 // (which Module it came from) 392 return false; 393 } 394 395 const uint64_t byte_size = GetByteSize().getValueOr(0); 396 if (data.GetByteSize() < byte_size) { 397 lldb::DataBufferSP data_sp(new DataBufferHeap(byte_size, '\0')); 398 data.SetData(data_sp); 399 } 400 401 uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, byte_size)); 402 if (dst != nullptr) { 403 if (address_type == eAddressTypeHost) { 404 // The address is an address in this process, so just copy it 405 if (addr == 0) 406 return false; 407 memcpy(dst, reinterpret_cast<uint8_t *>(addr), byte_size); 408 return true; 409 } else { 410 if (exe_ctx) { 411 Process *process = exe_ctx->GetProcessPtr(); 412 if (process) { 413 Status error; 414 return exe_ctx->GetProcessPtr()->ReadMemory(addr, dst, byte_size, 415 error) == byte_size; 416 } 417 } 418 } 419 } 420 return false; 421 } 422 423 bool Type::WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t addr, 424 AddressType address_type, DataExtractor &data) { 425 return false; 426 } 427 428 TypeList *Type::GetTypeList() { return GetSymbolFile()->GetTypeList(); } 429 430 const Declaration &Type::GetDeclaration() const { return m_decl; } 431 432 bool Type::ResolveClangType(ResolveState compiler_type_resolve_state) { 433 // TODO: This needs to consider the correct type system to use. 434 Type *encoding_type = nullptr; 435 if (!m_compiler_type.IsValid()) { 436 encoding_type = GetEncodingType(); 437 if (encoding_type) { 438 switch (m_encoding_uid_type) { 439 case eEncodingIsUID: { 440 CompilerType encoding_compiler_type = 441 encoding_type->GetForwardCompilerType(); 442 if (encoding_compiler_type.IsValid()) { 443 m_compiler_type = encoding_compiler_type; 444 m_flags.compiler_type_resolve_state = 445 encoding_type->m_flags.compiler_type_resolve_state; 446 } 447 } break; 448 449 case eEncodingIsConstUID: 450 m_compiler_type = 451 encoding_type->GetForwardCompilerType().AddConstModifier(); 452 break; 453 454 case eEncodingIsRestrictUID: 455 m_compiler_type = 456 encoding_type->GetForwardCompilerType().AddRestrictModifier(); 457 break; 458 459 case eEncodingIsVolatileUID: 460 m_compiler_type = 461 encoding_type->GetForwardCompilerType().AddVolatileModifier(); 462 break; 463 464 case eEncodingIsTypedefUID: 465 m_compiler_type = encoding_type->GetForwardCompilerType().CreateTypedef( 466 m_name.AsCString("__lldb_invalid_typedef_name"), 467 GetSymbolFile()->GetDeclContextContainingUID(GetID())); 468 m_name.Clear(); 469 break; 470 471 case eEncodingIsPointerUID: 472 m_compiler_type = 473 encoding_type->GetForwardCompilerType().GetPointerType(); 474 break; 475 476 case eEncodingIsLValueReferenceUID: 477 m_compiler_type = 478 encoding_type->GetForwardCompilerType().GetLValueReferenceType(); 479 break; 480 481 case eEncodingIsRValueReferenceUID: 482 m_compiler_type = 483 encoding_type->GetForwardCompilerType().GetRValueReferenceType(); 484 break; 485 486 default: 487 llvm_unreachable("Unhandled encoding_data_type."); 488 } 489 } else { 490 // We have no encoding type, return void? 491 TypeSystem *type_system = 492 m_symbol_file->GetTypeSystemForLanguage(eLanguageTypeC); 493 CompilerType void_compiler_type = 494 type_system->GetBasicTypeFromAST(eBasicTypeVoid); 495 switch (m_encoding_uid_type) { 496 case eEncodingIsUID: 497 m_compiler_type = void_compiler_type; 498 break; 499 500 case eEncodingIsConstUID: 501 m_compiler_type = void_compiler_type.AddConstModifier(); 502 break; 503 504 case eEncodingIsRestrictUID: 505 m_compiler_type = void_compiler_type.AddRestrictModifier(); 506 break; 507 508 case eEncodingIsVolatileUID: 509 m_compiler_type = void_compiler_type.AddVolatileModifier(); 510 break; 511 512 case eEncodingIsTypedefUID: 513 m_compiler_type = void_compiler_type.CreateTypedef( 514 m_name.AsCString("__lldb_invalid_typedef_name"), 515 GetSymbolFile()->GetDeclContextContainingUID(GetID())); 516 break; 517 518 case eEncodingIsPointerUID: 519 m_compiler_type = void_compiler_type.GetPointerType(); 520 break; 521 522 case eEncodingIsLValueReferenceUID: 523 m_compiler_type = void_compiler_type.GetLValueReferenceType(); 524 break; 525 526 case eEncodingIsRValueReferenceUID: 527 m_compiler_type = void_compiler_type.GetRValueReferenceType(); 528 break; 529 530 default: 531 llvm_unreachable("Unhandled encoding_data_type."); 532 } 533 } 534 535 // When we have a EncodingUID, our "m_flags.compiler_type_resolve_state" is 536 // set to eResolveStateUnresolved so we need to update it to say that we 537 // now have a forward declaration since that is what we created above. 538 if (m_compiler_type.IsValid()) 539 m_flags.compiler_type_resolve_state = eResolveStateForward; 540 } 541 542 // Check if we have a forward reference to a class/struct/union/enum? 543 if (compiler_type_resolve_state == eResolveStateLayout || 544 compiler_type_resolve_state == eResolveStateFull) { 545 // Check if we have a forward reference to a class/struct/union/enum? 546 if (m_compiler_type.IsValid() && 547 m_flags.compiler_type_resolve_state < compiler_type_resolve_state) { 548 m_flags.compiler_type_resolve_state = eResolveStateFull; 549 if (!m_compiler_type.IsDefined()) { 550 // We have a forward declaration, we need to resolve it to a complete 551 // definition. 552 m_symbol_file->CompleteType(m_compiler_type); 553 } 554 } 555 } 556 557 // If we have an encoding type, then we need to make sure it is resolved 558 // appropriately. 559 if (m_encoding_uid != LLDB_INVALID_UID) { 560 if (encoding_type == nullptr) 561 encoding_type = GetEncodingType(); 562 if (encoding_type) { 563 ResolveState encoding_compiler_type_resolve_state = 564 compiler_type_resolve_state; 565 566 if (compiler_type_resolve_state == eResolveStateLayout) { 567 switch (m_encoding_uid_type) { 568 case eEncodingIsPointerUID: 569 case eEncodingIsLValueReferenceUID: 570 case eEncodingIsRValueReferenceUID: 571 encoding_compiler_type_resolve_state = eResolveStateForward; 572 break; 573 default: 574 break; 575 } 576 } 577 encoding_type->ResolveClangType(encoding_compiler_type_resolve_state); 578 } 579 } 580 return m_compiler_type.IsValid(); 581 } 582 uint32_t Type::GetEncodingMask() { 583 uint32_t encoding_mask = 1u << m_encoding_uid_type; 584 Type *encoding_type = GetEncodingType(); 585 assert(encoding_type != this); 586 if (encoding_type) 587 encoding_mask |= encoding_type->GetEncodingMask(); 588 return encoding_mask; 589 } 590 591 CompilerType Type::GetFullCompilerType() { 592 ResolveClangType(eResolveStateFull); 593 return m_compiler_type; 594 } 595 596 CompilerType Type::GetLayoutCompilerType() { 597 ResolveClangType(eResolveStateLayout); 598 return m_compiler_type; 599 } 600 601 CompilerType Type::GetForwardCompilerType() { 602 ResolveClangType(eResolveStateForward); 603 return m_compiler_type; 604 } 605 606 int Type::Compare(const Type &a, const Type &b) { 607 // Just compare the UID values for now... 608 lldb::user_id_t a_uid = a.GetID(); 609 lldb::user_id_t b_uid = b.GetID(); 610 if (a_uid < b_uid) 611 return -1; 612 if (a_uid > b_uid) 613 return 1; 614 return 0; 615 } 616 617 ConstString Type::GetQualifiedName() { 618 return GetForwardCompilerType().GetConstTypeName(); 619 } 620 621 bool Type::GetTypeScopeAndBasename(const llvm::StringRef& name, 622 llvm::StringRef &scope, 623 llvm::StringRef &basename, 624 TypeClass &type_class) { 625 type_class = eTypeClassAny; 626 627 if (name.empty()) 628 return false; 629 630 basename = name; 631 if (basename.consume_front("struct ")) 632 type_class = eTypeClassStruct; 633 else if (basename.consume_front("class ")) 634 type_class = eTypeClassClass; 635 else if (basename.consume_front("union ")) 636 type_class = eTypeClassUnion; 637 else if (basename.consume_front("enum ")) 638 type_class = eTypeClassEnumeration; 639 else if (basename.consume_front("typedef ")) 640 type_class = eTypeClassTypedef; 641 642 size_t namespace_separator = basename.find("::"); 643 if (namespace_separator == llvm::StringRef::npos) 644 return false; 645 646 size_t template_begin = basename.find('<'); 647 while (namespace_separator != llvm::StringRef::npos) { 648 if (template_begin != llvm::StringRef::npos && 649 namespace_separator > template_begin) { 650 size_t template_depth = 1; 651 llvm::StringRef template_arg = 652 basename.drop_front(template_begin + 1); 653 while (template_depth > 0 && !template_arg.empty()) { 654 if (template_arg.front() == '<') 655 template_depth++; 656 else if (template_arg.front() == '>') 657 template_depth--; 658 template_arg = template_arg.drop_front(1); 659 } 660 if (template_depth != 0) 661 return false; // We have an invalid type name. Bail out. 662 if (template_arg.empty()) 663 break; // The template ends at the end of the full name. 664 basename = template_arg; 665 } else { 666 basename = basename.drop_front(namespace_separator + 2); 667 } 668 template_begin = basename.find('<'); 669 namespace_separator = basename.find("::"); 670 } 671 if (basename.size() < name.size()) { 672 scope = name.take_front(name.size() - basename.size()); 673 return true; 674 } 675 return false; 676 } 677 678 ModuleSP Type::GetModule() { 679 if (m_symbol_file) 680 return m_symbol_file->GetObjectFile()->GetModule(); 681 return ModuleSP(); 682 } 683 684 TypeAndOrName::TypeAndOrName(TypeSP &in_type_sp) { 685 if (in_type_sp) { 686 m_compiler_type = in_type_sp->GetForwardCompilerType(); 687 m_type_name = in_type_sp->GetName(); 688 } 689 } 690 691 TypeAndOrName::TypeAndOrName(const char *in_type_str) 692 : m_type_name(in_type_str) {} 693 694 TypeAndOrName::TypeAndOrName(ConstString &in_type_const_string) 695 : m_type_name(in_type_const_string) {} 696 697 bool TypeAndOrName::operator==(const TypeAndOrName &other) const { 698 if (m_compiler_type != other.m_compiler_type) 699 return false; 700 if (m_type_name != other.m_type_name) 701 return false; 702 return true; 703 } 704 705 bool TypeAndOrName::operator!=(const TypeAndOrName &other) const { 706 return !(*this == other); 707 } 708 709 ConstString TypeAndOrName::GetName() const { 710 if (m_type_name) 711 return m_type_name; 712 if (m_compiler_type) 713 return m_compiler_type.GetTypeName(); 714 return ConstString("<invalid>"); 715 } 716 717 void TypeAndOrName::SetName(ConstString type_name) { 718 m_type_name = type_name; 719 } 720 721 void TypeAndOrName::SetName(const char *type_name_cstr) { 722 m_type_name.SetCString(type_name_cstr); 723 } 724 725 void TypeAndOrName::SetTypeSP(lldb::TypeSP type_sp) { 726 if (type_sp) { 727 m_compiler_type = type_sp->GetForwardCompilerType(); 728 m_type_name = type_sp->GetName(); 729 } else 730 Clear(); 731 } 732 733 void TypeAndOrName::SetCompilerType(CompilerType compiler_type) { 734 m_compiler_type = compiler_type; 735 if (m_compiler_type) 736 m_type_name = m_compiler_type.GetTypeName(); 737 } 738 739 bool TypeAndOrName::IsEmpty() const { 740 return !((bool)m_type_name || (bool)m_compiler_type); 741 } 742 743 void TypeAndOrName::Clear() { 744 m_type_name.Clear(); 745 m_compiler_type.Clear(); 746 } 747 748 bool TypeAndOrName::HasName() const { return (bool)m_type_name; } 749 750 bool TypeAndOrName::HasCompilerType() const { 751 return m_compiler_type.IsValid(); 752 } 753 754 TypeImpl::TypeImpl(const lldb::TypeSP &type_sp) 755 : m_module_wp(), m_static_type(), m_dynamic_type() { 756 SetType(type_sp); 757 } 758 759 TypeImpl::TypeImpl(const CompilerType &compiler_type) 760 : m_module_wp(), m_static_type(), m_dynamic_type() { 761 SetType(compiler_type); 762 } 763 764 TypeImpl::TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic) 765 : m_module_wp(), m_static_type(), m_dynamic_type(dynamic) { 766 SetType(type_sp, dynamic); 767 } 768 769 TypeImpl::TypeImpl(const CompilerType &static_type, 770 const CompilerType &dynamic_type) 771 : m_module_wp(), m_static_type(), m_dynamic_type() { 772 SetType(static_type, dynamic_type); 773 } 774 775 void TypeImpl::SetType(const lldb::TypeSP &type_sp) { 776 if (type_sp) { 777 m_static_type = type_sp->GetForwardCompilerType(); 778 m_module_wp = type_sp->GetModule(); 779 } else { 780 m_static_type.Clear(); 781 m_module_wp = lldb::ModuleWP(); 782 } 783 } 784 785 void TypeImpl::SetType(const CompilerType &compiler_type) { 786 m_module_wp = lldb::ModuleWP(); 787 m_static_type = compiler_type; 788 } 789 790 void TypeImpl::SetType(const lldb::TypeSP &type_sp, 791 const CompilerType &dynamic) { 792 SetType(type_sp); 793 m_dynamic_type = dynamic; 794 } 795 796 void TypeImpl::SetType(const CompilerType &compiler_type, 797 const CompilerType &dynamic) { 798 m_module_wp = lldb::ModuleWP(); 799 m_static_type = compiler_type; 800 m_dynamic_type = dynamic; 801 } 802 803 bool TypeImpl::CheckModule(lldb::ModuleSP &module_sp) const { 804 // Check if we have a module for this type. If we do and the shared pointer 805 // is can be successfully initialized with m_module_wp, return true. Else 806 // return false if we didn't have a module, or if we had a module and it has 807 // been deleted. Any functions doing anything with a TypeSP in this TypeImpl 808 // class should call this function and only do anything with the ivars if 809 // this function returns true. If we have a module, the "module_sp" will be 810 // filled in with a strong reference to the module so that the module will at 811 // least stay around long enough for the type query to succeed. 812 module_sp = m_module_wp.lock(); 813 if (!module_sp) { 814 lldb::ModuleWP empty_module_wp; 815 // If either call to "std::weak_ptr::owner_before(...) value returns true, 816 // this indicates that m_module_wp once contained (possibly still does) a 817 // reference to a valid shared pointer. This helps us know if we had a 818 // valid reference to a section which is now invalid because the module it 819 // was in was deleted 820 if (empty_module_wp.owner_before(m_module_wp) || 821 m_module_wp.owner_before(empty_module_wp)) { 822 // m_module_wp had a valid reference to a module, but all strong 823 // references have been released and the module has been deleted 824 return false; 825 } 826 } 827 // We either successfully locked the module, or didn't have one to begin with 828 return true; 829 } 830 831 bool TypeImpl::operator==(const TypeImpl &rhs) const { 832 return m_static_type == rhs.m_static_type && 833 m_dynamic_type == rhs.m_dynamic_type; 834 } 835 836 bool TypeImpl::operator!=(const TypeImpl &rhs) const { 837 return !(*this == rhs); 838 } 839 840 bool TypeImpl::IsValid() const { 841 // just a name is not valid 842 ModuleSP module_sp; 843 if (CheckModule(module_sp)) 844 return m_static_type.IsValid() || m_dynamic_type.IsValid(); 845 return false; 846 } 847 848 TypeImpl::operator bool() const { return IsValid(); } 849 850 void TypeImpl::Clear() { 851 m_module_wp = lldb::ModuleWP(); 852 m_static_type.Clear(); 853 m_dynamic_type.Clear(); 854 } 855 856 ConstString TypeImpl::GetName() const { 857 ModuleSP module_sp; 858 if (CheckModule(module_sp)) { 859 if (m_dynamic_type) 860 return m_dynamic_type.GetTypeName(); 861 return m_static_type.GetTypeName(); 862 } 863 return ConstString(); 864 } 865 866 ConstString TypeImpl::GetDisplayTypeName() const { 867 ModuleSP module_sp; 868 if (CheckModule(module_sp)) { 869 if (m_dynamic_type) 870 return m_dynamic_type.GetDisplayTypeName(); 871 return m_static_type.GetDisplayTypeName(); 872 } 873 return ConstString(); 874 } 875 876 TypeImpl TypeImpl::GetPointerType() const { 877 ModuleSP module_sp; 878 if (CheckModule(module_sp)) { 879 if (m_dynamic_type.IsValid()) { 880 return TypeImpl(m_static_type.GetPointerType(), 881 m_dynamic_type.GetPointerType()); 882 } 883 return TypeImpl(m_static_type.GetPointerType()); 884 } 885 return TypeImpl(); 886 } 887 888 TypeImpl TypeImpl::GetPointeeType() const { 889 ModuleSP module_sp; 890 if (CheckModule(module_sp)) { 891 if (m_dynamic_type.IsValid()) { 892 return TypeImpl(m_static_type.GetPointeeType(), 893 m_dynamic_type.GetPointeeType()); 894 } 895 return TypeImpl(m_static_type.GetPointeeType()); 896 } 897 return TypeImpl(); 898 } 899 900 TypeImpl TypeImpl::GetReferenceType() const { 901 ModuleSP module_sp; 902 if (CheckModule(module_sp)) { 903 if (m_dynamic_type.IsValid()) { 904 return TypeImpl(m_static_type.GetLValueReferenceType(), 905 m_dynamic_type.GetLValueReferenceType()); 906 } 907 return TypeImpl(m_static_type.GetLValueReferenceType()); 908 } 909 return TypeImpl(); 910 } 911 912 TypeImpl TypeImpl::GetTypedefedType() const { 913 ModuleSP module_sp; 914 if (CheckModule(module_sp)) { 915 if (m_dynamic_type.IsValid()) { 916 return TypeImpl(m_static_type.GetTypedefedType(), 917 m_dynamic_type.GetTypedefedType()); 918 } 919 return TypeImpl(m_static_type.GetTypedefedType()); 920 } 921 return TypeImpl(); 922 } 923 924 TypeImpl TypeImpl::GetDereferencedType() const { 925 ModuleSP module_sp; 926 if (CheckModule(module_sp)) { 927 if (m_dynamic_type.IsValid()) { 928 return TypeImpl(m_static_type.GetNonReferenceType(), 929 m_dynamic_type.GetNonReferenceType()); 930 } 931 return TypeImpl(m_static_type.GetNonReferenceType()); 932 } 933 return TypeImpl(); 934 } 935 936 TypeImpl TypeImpl::GetUnqualifiedType() const { 937 ModuleSP module_sp; 938 if (CheckModule(module_sp)) { 939 if (m_dynamic_type.IsValid()) { 940 return TypeImpl(m_static_type.GetFullyUnqualifiedType(), 941 m_dynamic_type.GetFullyUnqualifiedType()); 942 } 943 return TypeImpl(m_static_type.GetFullyUnqualifiedType()); 944 } 945 return TypeImpl(); 946 } 947 948 TypeImpl TypeImpl::GetCanonicalType() const { 949 ModuleSP module_sp; 950 if (CheckModule(module_sp)) { 951 if (m_dynamic_type.IsValid()) { 952 return TypeImpl(m_static_type.GetCanonicalType(), 953 m_dynamic_type.GetCanonicalType()); 954 } 955 return TypeImpl(m_static_type.GetCanonicalType()); 956 } 957 return TypeImpl(); 958 } 959 960 CompilerType TypeImpl::GetCompilerType(bool prefer_dynamic) { 961 ModuleSP module_sp; 962 if (CheckModule(module_sp)) { 963 if (prefer_dynamic) { 964 if (m_dynamic_type.IsValid()) 965 return m_dynamic_type; 966 } 967 return m_static_type; 968 } 969 return CompilerType(); 970 } 971 972 TypeSystem *TypeImpl::GetTypeSystem(bool prefer_dynamic) { 973 ModuleSP module_sp; 974 if (CheckModule(module_sp)) { 975 if (prefer_dynamic) { 976 if (m_dynamic_type.IsValid()) 977 return m_dynamic_type.GetTypeSystem(); 978 } 979 return m_static_type.GetTypeSystem(); 980 } 981 return nullptr; 982 } 983 984 bool TypeImpl::GetDescription(lldb_private::Stream &strm, 985 lldb::DescriptionLevel description_level) { 986 ModuleSP module_sp; 987 if (CheckModule(module_sp)) { 988 if (m_dynamic_type.IsValid()) { 989 strm.Printf("Dynamic:\n"); 990 m_dynamic_type.DumpTypeDescription(&strm); 991 strm.Printf("\nStatic:\n"); 992 } 993 m_static_type.DumpTypeDescription(&strm); 994 } else { 995 strm.PutCString("Invalid TypeImpl module for type has been deleted\n"); 996 } 997 return true; 998 } 999 1000 bool TypeMemberFunctionImpl::IsValid() { 1001 return m_type.IsValid() && m_kind != lldb::eMemberFunctionKindUnknown; 1002 } 1003 1004 ConstString TypeMemberFunctionImpl::GetName() const { return m_name; } 1005 1006 ConstString TypeMemberFunctionImpl::GetMangledName() const { 1007 return m_decl.GetMangledName(); 1008 } 1009 1010 CompilerType TypeMemberFunctionImpl::GetType() const { return m_type; } 1011 1012 lldb::MemberFunctionKind TypeMemberFunctionImpl::GetKind() const { 1013 return m_kind; 1014 } 1015 1016 bool TypeMemberFunctionImpl::GetDescription(Stream &stream) { 1017 switch (m_kind) { 1018 case lldb::eMemberFunctionKindUnknown: 1019 return false; 1020 case lldb::eMemberFunctionKindConstructor: 1021 stream.Printf("constructor for %s", 1022 m_type.GetTypeName().AsCString("<unknown>")); 1023 break; 1024 case lldb::eMemberFunctionKindDestructor: 1025 stream.Printf("destructor for %s", 1026 m_type.GetTypeName().AsCString("<unknown>")); 1027 break; 1028 case lldb::eMemberFunctionKindInstanceMethod: 1029 stream.Printf("instance method %s of type %s", m_name.AsCString(), 1030 m_decl.GetDeclContext().GetName().AsCString()); 1031 break; 1032 case lldb::eMemberFunctionKindStaticMethod: 1033 stream.Printf("static method %s of type %s", m_name.AsCString(), 1034 m_decl.GetDeclContext().GetName().AsCString()); 1035 break; 1036 } 1037 return true; 1038 } 1039 1040 CompilerType TypeMemberFunctionImpl::GetReturnType() const { 1041 if (m_type) 1042 return m_type.GetFunctionReturnType(); 1043 return m_decl.GetFunctionReturnType(); 1044 } 1045 1046 size_t TypeMemberFunctionImpl::GetNumArguments() const { 1047 if (m_type) 1048 return m_type.GetNumberOfFunctionArguments(); 1049 else 1050 return m_decl.GetNumFunctionArguments(); 1051 } 1052 1053 CompilerType TypeMemberFunctionImpl::GetArgumentAtIndex(size_t idx) const { 1054 if (m_type) 1055 return m_type.GetFunctionArgumentAtIndex(idx); 1056 else 1057 return m_decl.GetFunctionArgumentType(idx); 1058 } 1059 1060 TypeEnumMemberImpl::TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp, 1061 ConstString name, 1062 const llvm::APSInt &value) 1063 : m_integer_type_sp(integer_type_sp), m_name(name), m_value(value), 1064 m_valid((bool)name && (bool)integer_type_sp) 1065 1066 {} 1067