SymbolFileDWARF.cpp revision 9ff34285e9658d948711077e9c265883b1425880
1//===-- SymbolFileDWARF.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#include "SymbolFileDWARF.h" 11 12// Other libraries and framework includes 13#include "clang/AST/ASTConsumer.h" 14#include "clang/AST/ASTContext.h" 15#include "clang/AST/Decl.h" 16#include "clang/AST/DeclGroup.h" 17#include "clang/AST/DeclObjC.h" 18#include "clang/AST/DeclTemplate.h" 19#include "clang/Basic/Builtins.h" 20#include "clang/Basic/IdentifierTable.h" 21#include "clang/Basic/LangOptions.h" 22#include "clang/Basic/SourceManager.h" 23#include "clang/Basic/TargetInfo.h" 24#include "clang/Basic/Specifiers.h" 25#include "clang/Sema/DeclSpec.h" 26 27#include "llvm/Support/Casting.h" 28 29#include "lldb/Core/Module.h" 30#include "lldb/Core/PluginManager.h" 31#include "lldb/Core/RegularExpression.h" 32#include "lldb/Core/Scalar.h" 33#include "lldb/Core/Section.h" 34#include "lldb/Core/StreamFile.h" 35#include "lldb/Core/StreamString.h" 36#include "lldb/Core/Timer.h" 37#include "lldb/Core/Value.h" 38 39#include "lldb/Host/Host.h" 40 41#include "lldb/Symbol/Block.h" 42#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h" 43#include "lldb/Symbol/CompileUnit.h" 44#include "lldb/Symbol/LineTable.h" 45#include "lldb/Symbol/ObjectFile.h" 46#include "lldb/Symbol/SymbolVendor.h" 47#include "lldb/Symbol/VariableList.h" 48 49#include "lldb/Target/ObjCLanguageRuntime.h" 50#include "lldb/Target/CPPLanguageRuntime.h" 51 52#include "DWARFCompileUnit.h" 53#include "DWARFDebugAbbrev.h" 54#include "DWARFDebugAranges.h" 55#include "DWARFDebugInfo.h" 56#include "DWARFDebugInfoEntry.h" 57#include "DWARFDebugLine.h" 58#include "DWARFDebugPubnames.h" 59#include "DWARFDebugRanges.h" 60#include "DWARFDIECollection.h" 61#include "DWARFFormValue.h" 62#include "DWARFLocationList.h" 63#include "LogChannelDWARF.h" 64#include "SymbolFileDWARFDebugMap.h" 65 66#include <map> 67 68//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN 69 70#ifdef ENABLE_DEBUG_PRINTF 71#include <stdio.h> 72#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__) 73#else 74#define DEBUG_PRINTF(fmt, ...) 75#endif 76 77#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1) 78 79using namespace lldb; 80using namespace lldb_private; 81 82static inline bool 83child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag) 84{ 85 switch (tag) 86 { 87 default: 88 break; 89 case DW_TAG_subprogram: 90 case DW_TAG_inlined_subroutine: 91 case DW_TAG_class_type: 92 case DW_TAG_structure_type: 93 case DW_TAG_union_type: 94 return true; 95 } 96 return false; 97} 98 99static AccessType 100DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility) 101{ 102 switch (dwarf_accessibility) 103 { 104 case DW_ACCESS_public: return eAccessPublic; 105 case DW_ACCESS_private: return eAccessPrivate; 106 case DW_ACCESS_protected: return eAccessProtected; 107 default: break; 108 } 109 return eAccessNone; 110} 111 112#if defined(LLDB_CONFIGURATION_DEBUG) or defined(LLDB_CONFIGURATION_RELEASE) 113 114class DIEStack 115{ 116public: 117 118 void Push (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) 119 { 120 m_dies.push_back (DIEInfo(cu, die)); 121 } 122 123 124 void LogDIEs (Log *log, SymbolFileDWARF *dwarf) 125 { 126 StreamString log_strm; 127 const size_t n = m_dies.size(); 128 log_strm.Printf("DIEStack[%zu]:\n", n); 129 for (size_t i=0; i<n; i++) 130 { 131 DWARFCompileUnit *cu = m_dies[i].cu; 132 const DWARFDebugInfoEntry *die = m_dies[i].die; 133 std::string qualified_name; 134 die->GetQualifiedName(dwarf, cu, qualified_name); 135 log_strm.Printf ("[%zu] 0x%8.8x: %s name='%s'\n", 136 i, 137 die->GetOffset(), 138 DW_TAG_value_to_name(die->Tag()), 139 qualified_name.c_str()); 140 } 141 log->PutCString(log_strm.GetData()); 142 } 143 void Pop () 144 { 145 m_dies.pop_back(); 146 } 147 148 class ScopedPopper 149 { 150 public: 151 ScopedPopper (DIEStack &die_stack) : 152 m_die_stack (die_stack), 153 m_valid (false) 154 { 155 } 156 157 void 158 Push (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) 159 { 160 m_valid = true; 161 m_die_stack.Push (cu, die); 162 } 163 164 ~ScopedPopper () 165 { 166 if (m_valid) 167 m_die_stack.Pop(); 168 } 169 170 171 172 protected: 173 DIEStack &m_die_stack; 174 bool m_valid; 175 }; 176 177protected: 178 struct DIEInfo { 179 DIEInfo (DWARFCompileUnit *c, const DWARFDebugInfoEntry *d) : 180 cu(c), 181 die(d) 182 { 183 } 184 DWARFCompileUnit *cu; 185 const DWARFDebugInfoEntry *die; 186 }; 187 typedef std::vector<DIEInfo> Stack; 188 Stack m_dies; 189}; 190#endif 191 192void 193SymbolFileDWARF::Initialize() 194{ 195 LogChannelDWARF::Initialize(); 196 PluginManager::RegisterPlugin (GetPluginNameStatic(), 197 GetPluginDescriptionStatic(), 198 CreateInstance); 199} 200 201void 202SymbolFileDWARF::Terminate() 203{ 204 PluginManager::UnregisterPlugin (CreateInstance); 205 LogChannelDWARF::Initialize(); 206} 207 208 209const char * 210SymbolFileDWARF::GetPluginNameStatic() 211{ 212 return "dwarf"; 213} 214 215const char * 216SymbolFileDWARF::GetPluginDescriptionStatic() 217{ 218 return "DWARF and DWARF3 debug symbol file reader."; 219} 220 221 222SymbolFile* 223SymbolFileDWARF::CreateInstance (ObjectFile* obj_file) 224{ 225 return new SymbolFileDWARF(obj_file); 226} 227 228TypeList * 229SymbolFileDWARF::GetTypeList () 230{ 231 if (m_debug_map_symfile) 232 return m_debug_map_symfile->GetTypeList(); 233 return m_obj_file->GetModule()->GetTypeList(); 234 235} 236 237//---------------------------------------------------------------------- 238// Gets the first parent that is a lexical block, function or inlined 239// subroutine, or compile unit. 240//---------------------------------------------------------------------- 241static const DWARFDebugInfoEntry * 242GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die) 243{ 244 const DWARFDebugInfoEntry *die; 245 for (die = child_die->GetParent(); die != NULL; die = die->GetParent()) 246 { 247 dw_tag_t tag = die->Tag(); 248 249 switch (tag) 250 { 251 case DW_TAG_compile_unit: 252 case DW_TAG_subprogram: 253 case DW_TAG_inlined_subroutine: 254 case DW_TAG_lexical_block: 255 return die; 256 } 257 } 258 return NULL; 259} 260 261 262SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) : 263 SymbolFile (objfile), 264 UserID (0), // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID 265 m_debug_map_symfile (NULL), 266 m_clang_tu_decl (NULL), 267 m_flags(), 268 m_data_debug_abbrev (), 269 m_data_debug_aranges (), 270 m_data_debug_frame (), 271 m_data_debug_info (), 272 m_data_debug_line (), 273 m_data_debug_loc (), 274 m_data_debug_ranges (), 275 m_data_debug_str (), 276 m_data_apple_names (), 277 m_data_apple_types (), 278 m_data_apple_namespaces (), 279 m_abbr(), 280 m_info(), 281 m_line(), 282 m_apple_names_ap (), 283 m_apple_types_ap (), 284 m_apple_namespaces_ap (), 285 m_apple_objc_ap (), 286 m_function_basename_index(), 287 m_function_fullname_index(), 288 m_function_method_index(), 289 m_function_selector_index(), 290 m_objc_class_selectors_index(), 291 m_global_index(), 292 m_type_index(), 293 m_namespace_index(), 294 m_indexed (false), 295 m_is_external_ast_source (false), 296 m_using_apple_tables (false), 297 m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate), 298 m_ranges(), 299 m_unique_ast_type_map () 300{ 301} 302 303SymbolFileDWARF::~SymbolFileDWARF() 304{ 305 if (m_is_external_ast_source) 306 { 307 ModuleSP module_sp (m_obj_file->GetModule()); 308 if (module_sp) 309 module_sp->GetClangASTContext().RemoveExternalSource (); 310 } 311} 312 313static const ConstString & 314GetDWARFMachOSegmentName () 315{ 316 static ConstString g_dwarf_section_name ("__DWARF"); 317 return g_dwarf_section_name; 318} 319 320UniqueDWARFASTTypeMap & 321SymbolFileDWARF::GetUniqueDWARFASTTypeMap () 322{ 323 if (m_debug_map_symfile) 324 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap (); 325 return m_unique_ast_type_map; 326} 327 328ClangASTContext & 329SymbolFileDWARF::GetClangASTContext () 330{ 331 if (m_debug_map_symfile) 332 return m_debug_map_symfile->GetClangASTContext (); 333 334 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext(); 335 if (!m_is_external_ast_source) 336 { 337 m_is_external_ast_source = true; 338 llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap ( 339 new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl, 340 SymbolFileDWARF::CompleteObjCInterfaceDecl, 341 SymbolFileDWARF::FindExternalVisibleDeclsByName, 342 SymbolFileDWARF::LayoutRecordType, 343 this)); 344 ast.SetExternalSource (ast_source_ap); 345 } 346 return ast; 347} 348 349void 350SymbolFileDWARF::InitializeObject() 351{ 352 // Install our external AST source callbacks so we can complete Clang types. 353 ModuleSP module_sp (m_obj_file->GetModule()); 354 if (module_sp) 355 { 356 const SectionList *section_list = m_obj_file->GetSectionList(); 357 358 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get(); 359 360 // Memory map the DWARF mach-o segment so we have everything mmap'ed 361 // to keep our heap memory usage down. 362 if (section) 363 m_obj_file->MemoryMapSectionData(section, m_dwarf_data); 364 } 365 get_apple_names_data(); 366 if (m_data_apple_names.GetByteSize() > 0) 367 { 368 m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), ".apple_names")); 369 if (m_apple_names_ap->IsValid()) 370 m_using_apple_tables = true; 371 else 372 m_apple_names_ap.reset(); 373 } 374 get_apple_types_data(); 375 if (m_data_apple_types.GetByteSize() > 0) 376 { 377 m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), ".apple_types")); 378 if (m_apple_types_ap->IsValid()) 379 m_using_apple_tables = true; 380 else 381 m_apple_types_ap.reset(); 382 } 383 384 get_apple_namespaces_data(); 385 if (m_data_apple_namespaces.GetByteSize() > 0) 386 { 387 m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), ".apple_namespaces")); 388 if (m_apple_namespaces_ap->IsValid()) 389 m_using_apple_tables = true; 390 else 391 m_apple_namespaces_ap.reset(); 392 } 393 394 get_apple_objc_data(); 395 if (m_data_apple_objc.GetByteSize() > 0) 396 { 397 m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc, get_debug_str_data(), ".apple_objc")); 398 if (m_apple_objc_ap->IsValid()) 399 m_using_apple_tables = true; 400 else 401 m_apple_objc_ap.reset(); 402 } 403} 404 405bool 406SymbolFileDWARF::SupportedVersion(uint16_t version) 407{ 408 return version == 2 || version == 3; 409} 410 411uint32_t 412SymbolFileDWARF::CalculateAbilities () 413{ 414 uint32_t abilities = 0; 415 if (m_obj_file != NULL) 416 { 417 const Section* section = NULL; 418 const SectionList *section_list = m_obj_file->GetSectionList(); 419 if (section_list == NULL) 420 return 0; 421 422 uint64_t debug_abbrev_file_size = 0; 423 uint64_t debug_aranges_file_size = 0; 424 uint64_t debug_frame_file_size = 0; 425 uint64_t debug_info_file_size = 0; 426 uint64_t debug_line_file_size = 0; 427 uint64_t debug_loc_file_size = 0; 428 uint64_t debug_macinfo_file_size = 0; 429 uint64_t debug_pubnames_file_size = 0; 430 uint64_t debug_pubtypes_file_size = 0; 431 uint64_t debug_ranges_file_size = 0; 432 uint64_t debug_str_file_size = 0; 433 434 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get(); 435 436 if (section) 437 section_list = §ion->GetChildren (); 438 439 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get(); 440 if (section != NULL) 441 { 442 debug_info_file_size = section->GetByteSize(); 443 444 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get(); 445 if (section) 446 debug_abbrev_file_size = section->GetByteSize(); 447 else 448 m_flags.Set (flagsGotDebugAbbrevData); 449 450 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get(); 451 if (section) 452 debug_aranges_file_size = section->GetByteSize(); 453 else 454 m_flags.Set (flagsGotDebugArangesData); 455 456 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get(); 457 if (section) 458 debug_frame_file_size = section->GetByteSize(); 459 else 460 m_flags.Set (flagsGotDebugFrameData); 461 462 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get(); 463 if (section) 464 debug_line_file_size = section->GetByteSize(); 465 else 466 m_flags.Set (flagsGotDebugLineData); 467 468 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get(); 469 if (section) 470 debug_loc_file_size = section->GetByteSize(); 471 else 472 m_flags.Set (flagsGotDebugLocData); 473 474 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get(); 475 if (section) 476 debug_macinfo_file_size = section->GetByteSize(); 477 else 478 m_flags.Set (flagsGotDebugMacInfoData); 479 480 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get(); 481 if (section) 482 debug_pubnames_file_size = section->GetByteSize(); 483 else 484 m_flags.Set (flagsGotDebugPubNamesData); 485 486 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get(); 487 if (section) 488 debug_pubtypes_file_size = section->GetByteSize(); 489 else 490 m_flags.Set (flagsGotDebugPubTypesData); 491 492 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get(); 493 if (section) 494 debug_ranges_file_size = section->GetByteSize(); 495 else 496 m_flags.Set (flagsGotDebugRangesData); 497 498 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get(); 499 if (section) 500 debug_str_file_size = section->GetByteSize(); 501 else 502 m_flags.Set (flagsGotDebugStrData); 503 } 504 505 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0) 506 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes; 507 508 if (debug_line_file_size > 0) 509 abilities |= LineTables; 510 511 if (debug_aranges_file_size > 0) 512 abilities |= AddressAcceleratorTable; 513 514 if (debug_pubnames_file_size > 0) 515 abilities |= FunctionAcceleratorTable; 516 517 if (debug_pubtypes_file_size > 0) 518 abilities |= TypeAcceleratorTable; 519 520 if (debug_macinfo_file_size > 0) 521 abilities |= MacroInformation; 522 523 if (debug_frame_file_size > 0) 524 abilities |= CallFrameInformation; 525 } 526 return abilities; 527} 528 529const DataExtractor& 530SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data) 531{ 532 if (m_flags.IsClear (got_flag)) 533 { 534 m_flags.Set (got_flag); 535 const SectionList *section_list = m_obj_file->GetSectionList(); 536 if (section_list) 537 { 538 SectionSP section_sp (section_list->FindSectionByType(sect_type, true)); 539 if (section_sp) 540 { 541 // See if we memory mapped the DWARF segment? 542 if (m_dwarf_data.GetByteSize()) 543 { 544 data.SetData(m_dwarf_data, section_sp->GetOffset (), section_sp->GetByteSize()); 545 } 546 else 547 { 548 if (m_obj_file->ReadSectionData (section_sp.get(), data) == 0) 549 data.Clear(); 550 } 551 } 552 } 553 } 554 return data; 555} 556 557const DataExtractor& 558SymbolFileDWARF::get_debug_abbrev_data() 559{ 560 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev); 561} 562 563const DataExtractor& 564SymbolFileDWARF::get_debug_aranges_data() 565{ 566 return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges); 567} 568 569const DataExtractor& 570SymbolFileDWARF::get_debug_frame_data() 571{ 572 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame); 573} 574 575const DataExtractor& 576SymbolFileDWARF::get_debug_info_data() 577{ 578 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info); 579} 580 581const DataExtractor& 582SymbolFileDWARF::get_debug_line_data() 583{ 584 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line); 585} 586 587const DataExtractor& 588SymbolFileDWARF::get_debug_loc_data() 589{ 590 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc); 591} 592 593const DataExtractor& 594SymbolFileDWARF::get_debug_ranges_data() 595{ 596 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges); 597} 598 599const DataExtractor& 600SymbolFileDWARF::get_debug_str_data() 601{ 602 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str); 603} 604 605const DataExtractor& 606SymbolFileDWARF::get_apple_names_data() 607{ 608 return GetCachedSectionData (flagsGotAppleNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names); 609} 610 611const DataExtractor& 612SymbolFileDWARF::get_apple_types_data() 613{ 614 return GetCachedSectionData (flagsGotAppleTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types); 615} 616 617const DataExtractor& 618SymbolFileDWARF::get_apple_namespaces_data() 619{ 620 return GetCachedSectionData (flagsGotAppleNamespacesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces); 621} 622 623const DataExtractor& 624SymbolFileDWARF::get_apple_objc_data() 625{ 626 return GetCachedSectionData (flagsGotAppleObjCData, eSectionTypeDWARFAppleObjC, m_data_apple_objc); 627} 628 629 630DWARFDebugAbbrev* 631SymbolFileDWARF::DebugAbbrev() 632{ 633 if (m_abbr.get() == NULL) 634 { 635 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data(); 636 if (debug_abbrev_data.GetByteSize() > 0) 637 { 638 m_abbr.reset(new DWARFDebugAbbrev()); 639 if (m_abbr.get()) 640 m_abbr->Parse(debug_abbrev_data); 641 } 642 } 643 return m_abbr.get(); 644} 645 646const DWARFDebugAbbrev* 647SymbolFileDWARF::DebugAbbrev() const 648{ 649 return m_abbr.get(); 650} 651 652 653DWARFDebugInfo* 654SymbolFileDWARF::DebugInfo() 655{ 656 if (m_info.get() == NULL) 657 { 658 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 659 if (get_debug_info_data().GetByteSize() > 0) 660 { 661 m_info.reset(new DWARFDebugInfo()); 662 if (m_info.get()) 663 { 664 m_info->SetDwarfData(this); 665 } 666 } 667 } 668 return m_info.get(); 669} 670 671const DWARFDebugInfo* 672SymbolFileDWARF::DebugInfo() const 673{ 674 return m_info.get(); 675} 676 677DWARFCompileUnit* 678SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid) 679{ 680 DWARFDebugInfo* info = DebugInfo(); 681 if (info && UserIDMatches(cu_uid)) 682 return info->GetCompileUnit((dw_offset_t)cu_uid).get(); 683 return NULL; 684} 685 686 687DWARFDebugRanges* 688SymbolFileDWARF::DebugRanges() 689{ 690 if (m_ranges.get() == NULL) 691 { 692 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 693 if (get_debug_ranges_data().GetByteSize() > 0) 694 { 695 m_ranges.reset(new DWARFDebugRanges()); 696 if (m_ranges.get()) 697 m_ranges->Extract(this); 698 } 699 } 700 return m_ranges.get(); 701} 702 703const DWARFDebugRanges* 704SymbolFileDWARF::DebugRanges() const 705{ 706 return m_ranges.get(); 707} 708 709bool 710SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp) 711{ 712 if (curr_cu != NULL) 713 { 714 ModuleSP module_sp (m_obj_file->GetModule()); 715 if (!module_sp) 716 return false; 717 718 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly (); 719 if (cu_die) 720 { 721 const char * cu_die_name = cu_die->GetName(this, curr_cu); 722 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL); 723 LanguageType cu_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0); 724 if (cu_die_name) 725 { 726 std::string ramapped_file; 727 FileSpec cu_file_spec; 728 729 if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0') 730 { 731 // If we have a full path to the compile unit, we don't need to resolve 732 // the file. This can be expensive e.g. when the source files are NFS mounted. 733 if (module_sp->RemapSourceFile(cu_die_name, ramapped_file)) 734 cu_file_spec.SetFile (ramapped_file.c_str(), false); 735 else 736 cu_file_spec.SetFile (cu_die_name, false); 737 } 738 else 739 { 740 std::string fullpath(cu_comp_dir); 741 if (*fullpath.rbegin() != '/') 742 fullpath += '/'; 743 fullpath += cu_die_name; 744 if (module_sp->RemapSourceFile (fullpath.c_str(), ramapped_file)) 745 cu_file_spec.SetFile (ramapped_file.c_str(), false); 746 else 747 cu_file_spec.SetFile (fullpath.c_str(), false); 748 } 749 750 compile_unit_sp.reset(new CompileUnit (module_sp, 751 curr_cu, 752 cu_file_spec, 753 MakeUserID(curr_cu->GetOffset()), 754 cu_language)); 755 if (compile_unit_sp.get()) 756 { 757 curr_cu->SetUserData(compile_unit_sp.get()); 758 return true; 759 } 760 } 761 } 762 } 763 return false; 764} 765 766uint32_t 767SymbolFileDWARF::GetNumCompileUnits() 768{ 769 DWARFDebugInfo* info = DebugInfo(); 770 if (info) 771 return info->GetNumCompileUnits(); 772 return 0; 773} 774 775CompUnitSP 776SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) 777{ 778 CompUnitSP comp_unit; 779 DWARFDebugInfo* info = DebugInfo(); 780 if (info) 781 { 782 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx); 783 if (curr_cu != NULL) 784 { 785 // Our symbol vendor shouldn't be asking us to add a compile unit that 786 // has already been added to it, which this DWARF plug-in knows as it 787 // stores the lldb compile unit (CompileUnit) pointer in each 788 // DWARFCompileUnit object when it gets added. 789 assert(curr_cu->GetUserData() == NULL); 790 ParseCompileUnit(curr_cu, comp_unit); 791 } 792 } 793 return comp_unit; 794} 795 796static void 797AddRangesToBlock (Block& block, 798 DWARFDebugRanges::RangeList& ranges, 799 addr_t block_base_addr) 800{ 801 const size_t num_ranges = ranges.GetSize(); 802 for (size_t i = 0; i<num_ranges; ++i) 803 { 804 const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i); 805 const addr_t range_base = range.GetRangeBase(); 806 assert (range_base >= block_base_addr); 807 block.AddRange(Block::Range (range_base - block_base_addr, range.GetByteSize()));; 808 } 809 block.FinalizeRanges (); 810} 811 812 813Function * 814SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die) 815{ 816 DWARFDebugRanges::RangeList func_ranges; 817 const char *name = NULL; 818 const char *mangled = NULL; 819 int decl_file = 0; 820 int decl_line = 0; 821 int decl_column = 0; 822 int call_file = 0; 823 int call_line = 0; 824 int call_column = 0; 825 DWARFExpression frame_base; 826 827 assert (die->Tag() == DW_TAG_subprogram); 828 829 if (die->Tag() != DW_TAG_subprogram) 830 return NULL; 831 832 if (die->GetDIENamesAndRanges (this, 833 dwarf_cu, 834 name, 835 mangled, 836 func_ranges, 837 decl_file, 838 decl_line, 839 decl_column, 840 call_file, 841 call_line, 842 call_column, 843 &frame_base)) 844 { 845 // Union of all ranges in the function DIE (if the function is discontiguous) 846 AddressRange func_range; 847 lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase (0); 848 lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd (0); 849 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr) 850 { 851 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList()); 852 if (func_range.GetBaseAddress().IsValid()) 853 func_range.SetByteSize(highest_func_addr - lowest_func_addr); 854 } 855 856 if (func_range.GetBaseAddress().IsValid()) 857 { 858 Mangled func_name; 859 if (mangled) 860 func_name.SetValue(mangled, true); 861 else if (name) 862 func_name.SetValue(name, false); 863 864 FunctionSP func_sp; 865 std::auto_ptr<Declaration> decl_ap; 866 if (decl_file != 0 || decl_line != 0 || decl_column != 0) 867 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), 868 decl_line, 869 decl_column)); 870 871 // Supply the type _only_ if it has already been parsed 872 Type *func_type = m_die_to_type.lookup (die); 873 874 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED); 875 876 func_range.GetBaseAddress().ResolveLinkedAddress(); 877 878 const user_id_t func_user_id = MakeUserID(die->GetOffset()); 879 func_sp.reset(new Function (sc.comp_unit, 880 func_user_id, // UserID is the DIE offset 881 func_user_id, 882 func_name, 883 func_type, 884 func_range)); // first address range 885 886 if (func_sp.get() != NULL) 887 { 888 if (frame_base.IsValid()) 889 func_sp->GetFrameBaseExpression() = frame_base; 890 sc.comp_unit->AddFunction(func_sp); 891 return func_sp.get(); 892 } 893 } 894 } 895 return NULL; 896} 897 898size_t 899SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) 900{ 901 assert (sc.comp_unit); 902 size_t functions_added = 0; 903 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 904 if (dwarf_cu) 905 { 906 DWARFDIECollection function_dies; 907 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies); 908 size_t func_idx; 909 for (func_idx = 0; func_idx < num_funtions; ++func_idx) 910 { 911 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx); 912 if (sc.comp_unit->FindFunctionByUID (MakeUserID(die->GetOffset())).get() == NULL) 913 { 914 if (ParseCompileUnitFunction(sc, dwarf_cu, die)) 915 ++functions_added; 916 } 917 } 918 //FixupTypes(); 919 } 920 return functions_added; 921} 922 923bool 924SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) 925{ 926 assert (sc.comp_unit); 927 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 928 assert (curr_cu); 929 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly(); 930 931 if (cu_die) 932 { 933 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL); 934 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_stmt_list, DW_INVALID_OFFSET); 935 936 // All file indexes in DWARF are one based and a file of index zero is 937 // supposed to be the compile unit itself. 938 support_files.Append (*sc.comp_unit); 939 940 return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, stmt_list, support_files); 941 } 942 return false; 943} 944 945struct ParseDWARFLineTableCallbackInfo 946{ 947 LineTable* line_table; 948 const SectionList *section_list; 949 lldb::addr_t prev_sect_file_base_addr; 950 lldb::addr_t curr_sect_file_base_addr; 951 bool is_oso_for_debug_map; 952 bool prev_in_final_executable; 953 DWARFDebugLine::Row prev_row; 954 SectionSP prev_section_sp; 955 SectionSP curr_section_sp; 956}; 957 958//---------------------------------------------------------------------- 959// ParseStatementTableCallback 960//---------------------------------------------------------------------- 961static void 962ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData) 963{ 964 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table; 965 if (state.row == DWARFDebugLine::State::StartParsingLineTable) 966 { 967 // Just started parsing the line table 968 } 969 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) 970 { 971 // Done parsing line table, nothing to do for the cleanup 972 } 973 else 974 { 975 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData; 976 // We have a new row, lets append it 977 978 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false) 979 { 980 info->prev_section_sp = info->curr_section_sp; 981 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr; 982 // If this is an end sequence entry, then we subtract one from the 983 // address to make sure we get an address that is not the end of 984 // a section. 985 if (state.end_sequence && state.address != 0) 986 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1); 987 else 988 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address); 989 990 if (info->curr_section_sp.get()) 991 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress (); 992 else 993 info->curr_sect_file_base_addr = 0; 994 } 995 if (info->curr_section_sp.get()) 996 { 997 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr; 998 // Check for the fancy section magic to determine if we 999 1000 if (info->is_oso_for_debug_map) 1001 { 1002 // When this is a debug map object file that contains DWARF 1003 // (referenced from an N_OSO debug map nlist entry) we will have 1004 // a file address in the file range for our section from the 1005 // original .o file, and a load address in the executable that 1006 // contains the debug map. 1007 // 1008 // If the sections for the file range and load range are 1009 // different, we have a remapped section for the function and 1010 // this address is resolved. If they are the same, then the 1011 // function for this address didn't make it into the final 1012 // executable. 1013 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL; 1014 1015 // If we are doing DWARF with debug map, then we need to carefully 1016 // add each line table entry as there may be gaps as functions 1017 // get moved around or removed. 1018 if (!info->prev_row.end_sequence && info->prev_section_sp.get()) 1019 { 1020 if (info->prev_in_final_executable) 1021 { 1022 bool terminate_previous_entry = false; 1023 if (!curr_in_final_executable) 1024 { 1025 // Check for the case where the previous line entry 1026 // in a function made it into the final executable, 1027 // yet the current line entry falls in a function 1028 // that didn't. The line table used to be contiguous 1029 // through this address range but now it isn't. We 1030 // need to terminate the previous line entry so 1031 // that we can reconstruct the line range correctly 1032 // for it and to keep the line table correct. 1033 terminate_previous_entry = true; 1034 } 1035 else if (info->curr_section_sp.get() != info->prev_section_sp.get()) 1036 { 1037 // Check for cases where the line entries used to be 1038 // contiguous address ranges, but now they aren't. 1039 // This can happen when order files specify the 1040 // ordering of the functions. 1041 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr; 1042 Section *curr_sect = info->curr_section_sp.get(); 1043 Section *prev_sect = info->prev_section_sp.get(); 1044 assert (curr_sect->GetLinkedSection()); 1045 assert (prev_sect->GetLinkedSection()); 1046 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address; 1047 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset; 1048 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset; 1049 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr; 1050 if (object_file_addr_delta != linked_file_addr_delta) 1051 terminate_previous_entry = true; 1052 } 1053 1054 if (terminate_previous_entry) 1055 { 1056 line_table->InsertLineEntry (info->prev_section_sp, 1057 state.address - info->prev_sect_file_base_addr, 1058 info->prev_row.line, 1059 info->prev_row.column, 1060 info->prev_row.file, 1061 false, // is_stmt 1062 false, // basic_block 1063 false, // state.prologue_end 1064 false, // state.epilogue_begin 1065 true); // end_sequence); 1066 } 1067 } 1068 } 1069 1070 if (curr_in_final_executable) 1071 { 1072 line_table->InsertLineEntry (info->curr_section_sp, 1073 curr_line_section_offset, 1074 state.line, 1075 state.column, 1076 state.file, 1077 state.is_stmt, 1078 state.basic_block, 1079 state.prologue_end, 1080 state.epilogue_begin, 1081 state.end_sequence); 1082 info->prev_section_sp = info->curr_section_sp; 1083 } 1084 else 1085 { 1086 // If the current address didn't make it into the final 1087 // executable, the current section will be the __text 1088 // segment in the .o file, so we need to clear this so 1089 // we can catch the next function that did make it into 1090 // the final executable. 1091 info->prev_section_sp.reset(); 1092 info->curr_section_sp.reset(); 1093 } 1094 1095 info->prev_in_final_executable = curr_in_final_executable; 1096 } 1097 else 1098 { 1099 // We are not in an object file that contains DWARF for an 1100 // N_OSO, this is just a normal DWARF file. The DWARF spec 1101 // guarantees that the addresses will be in increasing order 1102 // so, since we store line tables in file address order, we 1103 // can always just append the line entry without needing to 1104 // search for the correct insertion point (we don't need to 1105 // use LineEntry::InsertLineEntry()). 1106 line_table->AppendLineEntry (info->curr_section_sp, 1107 curr_line_section_offset, 1108 state.line, 1109 state.column, 1110 state.file, 1111 state.is_stmt, 1112 state.basic_block, 1113 state.prologue_end, 1114 state.epilogue_begin, 1115 state.end_sequence); 1116 } 1117 } 1118 1119 info->prev_row = state; 1120 } 1121} 1122 1123bool 1124SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc) 1125{ 1126 assert (sc.comp_unit); 1127 if (sc.comp_unit->GetLineTable() != NULL) 1128 return true; 1129 1130 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 1131 if (dwarf_cu) 1132 { 1133 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly(); 1134 if (dwarf_cu_die) 1135 { 1136 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET); 1137 if (cu_line_offset != DW_INVALID_OFFSET) 1138 { 1139 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit)); 1140 if (line_table_ap.get()) 1141 { 1142 ParseDWARFLineTableCallbackInfo info = { 1143 line_table_ap.get(), 1144 m_obj_file->GetSectionList(), 1145 0, 1146 0, 1147 m_debug_map_symfile != NULL, 1148 false, 1149 DWARFDebugLine::Row(), 1150 SectionSP(), 1151 SectionSP() 1152 }; 1153 uint32_t offset = cu_line_offset; 1154 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info); 1155 sc.comp_unit->SetLineTable(line_table_ap.release()); 1156 return true; 1157 } 1158 } 1159 } 1160 } 1161 return false; 1162} 1163 1164size_t 1165SymbolFileDWARF::ParseFunctionBlocks 1166( 1167 const SymbolContext& sc, 1168 Block *parent_block, 1169 DWARFCompileUnit* dwarf_cu, 1170 const DWARFDebugInfoEntry *die, 1171 addr_t subprogram_low_pc, 1172 uint32_t depth 1173) 1174{ 1175 size_t blocks_added = 0; 1176 while (die != NULL) 1177 { 1178 dw_tag_t tag = die->Tag(); 1179 1180 switch (tag) 1181 { 1182 case DW_TAG_inlined_subroutine: 1183 case DW_TAG_subprogram: 1184 case DW_TAG_lexical_block: 1185 { 1186 Block *block = NULL; 1187 if (tag == DW_TAG_subprogram) 1188 { 1189 // Skip any DW_TAG_subprogram DIEs that are inside 1190 // of a normal or inlined functions. These will be 1191 // parsed on their own as separate entities. 1192 1193 if (depth > 0) 1194 break; 1195 1196 block = parent_block; 1197 } 1198 else 1199 { 1200 BlockSP block_sp(new Block (MakeUserID(die->GetOffset()))); 1201 parent_block->AddChild(block_sp); 1202 block = block_sp.get(); 1203 } 1204 DWARFDebugRanges::RangeList ranges; 1205 const char *name = NULL; 1206 const char *mangled_name = NULL; 1207 1208 int decl_file = 0; 1209 int decl_line = 0; 1210 int decl_column = 0; 1211 int call_file = 0; 1212 int call_line = 0; 1213 int call_column = 0; 1214 if (die->GetDIENamesAndRanges (this, 1215 dwarf_cu, 1216 name, 1217 mangled_name, 1218 ranges, 1219 decl_file, decl_line, decl_column, 1220 call_file, call_line, call_column)) 1221 { 1222 if (tag == DW_TAG_subprogram) 1223 { 1224 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS); 1225 subprogram_low_pc = ranges.GetMinRangeBase(0); 1226 } 1227 else if (tag == DW_TAG_inlined_subroutine) 1228 { 1229 // We get called here for inlined subroutines in two ways. 1230 // The first time is when we are making the Function object 1231 // for this inlined concrete instance. Since we're creating a top level block at 1232 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to 1233 // adjust the containing address. 1234 // The second time is when we are parsing the blocks inside the function that contains 1235 // the inlined concrete instance. Since these will be blocks inside the containing "real" 1236 // function the offset will be for that function. 1237 if (subprogram_low_pc == LLDB_INVALID_ADDRESS) 1238 { 1239 subprogram_low_pc = ranges.GetMinRangeBase(0); 1240 } 1241 } 1242 1243 AddRangesToBlock (*block, ranges, subprogram_low_pc); 1244 1245 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL)) 1246 { 1247 std::auto_ptr<Declaration> decl_ap; 1248 if (decl_file != 0 || decl_line != 0 || decl_column != 0) 1249 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), 1250 decl_line, decl_column)); 1251 1252 std::auto_ptr<Declaration> call_ap; 1253 if (call_file != 0 || call_line != 0 || call_column != 0) 1254 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), 1255 call_line, call_column)); 1256 1257 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get()); 1258 } 1259 1260 ++blocks_added; 1261 1262 if (die->HasChildren()) 1263 { 1264 blocks_added += ParseFunctionBlocks (sc, 1265 block, 1266 dwarf_cu, 1267 die->GetFirstChild(), 1268 subprogram_low_pc, 1269 depth + 1); 1270 } 1271 } 1272 } 1273 break; 1274 default: 1275 break; 1276 } 1277 1278 // Only parse siblings of the block if we are not at depth zero. A depth 1279 // of zero indicates we are currently parsing the top level 1280 // DW_TAG_subprogram DIE 1281 1282 if (depth == 0) 1283 die = NULL; 1284 else 1285 die = die->GetSibling(); 1286 } 1287 return blocks_added; 1288} 1289 1290bool 1291SymbolFileDWARF::ParseTemplateDIE (DWARFCompileUnit* dwarf_cu, 1292 const DWARFDebugInfoEntry *die, 1293 ClangASTContext::TemplateParameterInfos &template_param_infos) 1294{ 1295 const dw_tag_t tag = die->Tag(); 1296 1297 switch (tag) 1298 { 1299 case DW_TAG_template_type_parameter: 1300 case DW_TAG_template_value_parameter: 1301 { 1302 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 1303 1304 DWARFDebugInfoEntry::Attributes attributes; 1305 const size_t num_attributes = die->GetAttributes (this, 1306 dwarf_cu, 1307 fixed_form_sizes, 1308 attributes); 1309 const char *name = NULL; 1310 Type *lldb_type = NULL; 1311 clang_type_t clang_type = NULL; 1312 uint64_t uval64 = 0; 1313 bool uval64_valid = false; 1314 if (num_attributes > 0) 1315 { 1316 DWARFFormValue form_value; 1317 for (size_t i=0; i<num_attributes; ++i) 1318 { 1319 const dw_attr_t attr = attributes.AttributeAtIndex(i); 1320 1321 switch (attr) 1322 { 1323 case DW_AT_name: 1324 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 1325 name = form_value.AsCString(&get_debug_str_data()); 1326 break; 1327 1328 case DW_AT_type: 1329 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 1330 { 1331 const dw_offset_t type_die_offset = form_value.Reference(dwarf_cu); 1332 lldb_type = ResolveTypeUID(type_die_offset); 1333 if (lldb_type) 1334 clang_type = lldb_type->GetClangForwardType(); 1335 } 1336 break; 1337 1338 case DW_AT_const_value: 1339 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 1340 { 1341 uval64_valid = true; 1342 uval64 = form_value.Unsigned(); 1343 } 1344 break; 1345 default: 1346 break; 1347 } 1348 } 1349 1350 if (name && lldb_type && clang_type) 1351 { 1352 bool is_signed = false; 1353 template_param_infos.names.push_back(name); 1354 clang::QualType clang_qual_type (clang::QualType::getFromOpaquePtr (clang_type)); 1355 if (tag == DW_TAG_template_value_parameter && ClangASTContext::IsIntegerType (clang_type, is_signed) && uval64_valid) 1356 { 1357 llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed); 1358 template_param_infos.args.push_back (clang::TemplateArgument (llvm::APSInt(apint), clang_qual_type)); 1359 } 1360 else 1361 { 1362 template_param_infos.args.push_back (clang::TemplateArgument (clang_qual_type)); 1363 } 1364 } 1365 else 1366 { 1367 return false; 1368 } 1369 1370 } 1371 } 1372 return true; 1373 1374 default: 1375 break; 1376 } 1377 return false; 1378} 1379 1380bool 1381SymbolFileDWARF::ParseTemplateParameterInfos (DWARFCompileUnit* dwarf_cu, 1382 const DWARFDebugInfoEntry *parent_die, 1383 ClangASTContext::TemplateParameterInfos &template_param_infos) 1384{ 1385 1386 if (parent_die == NULL) 1387 return NULL; 1388 1389 Args template_parameter_names; 1390 for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild(); 1391 die != NULL; 1392 die = die->GetSibling()) 1393 { 1394 const dw_tag_t tag = die->Tag(); 1395 1396 switch (tag) 1397 { 1398 case DW_TAG_template_type_parameter: 1399 case DW_TAG_template_value_parameter: 1400 ParseTemplateDIE (dwarf_cu, die, template_param_infos); 1401 break; 1402 1403 default: 1404 break; 1405 } 1406 } 1407 if (template_param_infos.args.empty()) 1408 return false; 1409 return template_param_infos.args.size() == template_param_infos.names.size(); 1410} 1411 1412clang::ClassTemplateDecl * 1413SymbolFileDWARF::ParseClassTemplateDecl (clang::DeclContext *decl_ctx, 1414 lldb::AccessType access_type, 1415 const char *parent_name, 1416 int tag_decl_kind, 1417 const ClangASTContext::TemplateParameterInfos &template_param_infos) 1418{ 1419 if (template_param_infos.IsValid()) 1420 { 1421 std::string template_basename(parent_name); 1422 template_basename.erase (template_basename.find('<')); 1423 ClangASTContext &ast = GetClangASTContext(); 1424 1425 return ast.CreateClassTemplateDecl (decl_ctx, 1426 access_type, 1427 template_basename.c_str(), 1428 tag_decl_kind, 1429 template_param_infos); 1430 } 1431 return NULL; 1432} 1433 1434size_t 1435SymbolFileDWARF::ParseChildMembers 1436( 1437 const SymbolContext& sc, 1438 DWARFCompileUnit* dwarf_cu, 1439 const DWARFDebugInfoEntry *parent_die, 1440 clang_type_t class_clang_type, 1441 const LanguageType class_language, 1442 std::vector<clang::CXXBaseSpecifier *>& base_classes, 1443 std::vector<int>& member_accessibilities, 1444 DWARFDIECollection& member_function_dies, 1445 AccessType& default_accessibility, 1446 bool &is_a_class, 1447 LayoutInfo &layout_info 1448) 1449{ 1450 if (parent_die == NULL) 1451 return 0; 1452 1453 size_t count = 0; 1454 const DWARFDebugInfoEntry *die; 1455 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 1456 uint32_t member_idx = 0; 1457 1458 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 1459 { 1460 dw_tag_t tag = die->Tag(); 1461 1462 switch (tag) 1463 { 1464 case DW_TAG_member: 1465 { 1466 DWARFDebugInfoEntry::Attributes attributes; 1467 const size_t num_attributes = die->GetAttributes (this, 1468 dwarf_cu, 1469 fixed_form_sizes, 1470 attributes); 1471 if (num_attributes > 0) 1472 { 1473 Declaration decl; 1474 //DWARFExpression location; 1475 const char *name = NULL; 1476 const char *prop_name = NULL; 1477 const char *prop_getter_name = NULL; 1478 const char *prop_setter_name = NULL; 1479 uint32_t prop_attributes = 0; 1480 1481 1482 bool is_artificial = false; 1483 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 1484 AccessType accessibility = eAccessNone; 1485 uint32_t member_byte_offset = UINT32_MAX; 1486 size_t byte_size = 0; 1487 size_t bit_offset = 0; 1488 size_t bit_size = 0; 1489 uint32_t i; 1490 for (i=0; i<num_attributes && !is_artificial; ++i) 1491 { 1492 const dw_attr_t attr = attributes.AttributeAtIndex(i); 1493 DWARFFormValue form_value; 1494 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 1495 { 1496 switch (attr) 1497 { 1498 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 1499 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 1500 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 1501 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 1502 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 1503 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break; 1504 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break; 1505 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 1506 case DW_AT_data_member_location: 1507 if (form_value.BlockData()) 1508 { 1509 Value initialValue(0); 1510 Value memberOffset(0); 1511 const DataExtractor& debug_info_data = get_debug_info_data(); 1512 uint32_t block_length = form_value.Unsigned(); 1513 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 1514 if (DWARFExpression::Evaluate(NULL, // ExecutionContext * 1515 NULL, // clang::ASTContext * 1516 NULL, // ClangExpressionVariableList * 1517 NULL, // ClangExpressionDeclMap * 1518 NULL, // RegisterContext * 1519 debug_info_data, 1520 block_offset, 1521 block_length, 1522 eRegisterKindDWARF, 1523 &initialValue, 1524 memberOffset, 1525 NULL)) 1526 { 1527 member_byte_offset = memberOffset.ResolveValue(NULL, NULL).UInt(); 1528 } 1529 } 1530 break; 1531 1532 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break; 1533 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break; 1534 case DW_AT_APPLE_property_name: prop_name = form_value.AsCString(&get_debug_str_data()); break; 1535 case DW_AT_APPLE_property_getter: prop_getter_name = form_value.AsCString(&get_debug_str_data()); break; 1536 case DW_AT_APPLE_property_setter: prop_setter_name = form_value.AsCString(&get_debug_str_data()); break; 1537 case DW_AT_APPLE_property_attribute: prop_attributes = form_value.Unsigned(); break; 1538 1539 default: 1540 case DW_AT_declaration: 1541 case DW_AT_description: 1542 case DW_AT_mutable: 1543 case DW_AT_visibility: 1544 case DW_AT_sibling: 1545 break; 1546 } 1547 } 1548 } 1549 1550 // Clang has a DWARF generation bug where sometimes it 1551 // represents fields that are references with bad byte size 1552 // and bit size/offset information such as: 1553 // 1554 // DW_AT_byte_size( 0x00 ) 1555 // DW_AT_bit_size( 0x40 ) 1556 // DW_AT_bit_offset( 0xffffffffffffffc0 ) 1557 // 1558 // So check the bit offset to make sure it is sane, and if 1559 // the values are not sane, remove them. If we don't do this 1560 // then we will end up with a crash if we try to use this 1561 // type in an expression when clang becomes unhappy with its 1562 // recycled debug info. 1563 1564 if (bit_offset > 128) 1565 { 1566 bit_size = 0; 1567 bit_offset = 0; 1568 } 1569 1570 // FIXME: Make Clang ignore Objective-C accessibility for expressions 1571 if (class_language == eLanguageTypeObjC || 1572 class_language == eLanguageTypeObjC_plus_plus) 1573 accessibility = eAccessNone; 1574 1575 if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name)) 1576 { 1577 // Not all compilers will mark the vtable pointer 1578 // member as artificial (llvm-gcc). We can't have 1579 // the virtual members in our classes otherwise it 1580 // throws off all child offsets since we end up 1581 // having and extra pointer sized member in our 1582 // class layouts. 1583 is_artificial = true; 1584 } 1585 1586 if (is_artificial == false) 1587 { 1588 Type *member_type = ResolveTypeUID(encoding_uid); 1589 clang::FieldDecl *field_decl = NULL; 1590 if (member_type) 1591 { 1592 if (accessibility == eAccessNone) 1593 accessibility = default_accessibility; 1594 member_accessibilities.push_back(accessibility); 1595 1596 field_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type, 1597 name, 1598 member_type->GetClangLayoutType(), 1599 accessibility, 1600 bit_size); 1601 } 1602 else 1603 { 1604 if (name) 1605 GetObjectFile()->GetModule()->ReportError ("0x%8.8llx: DW_TAG_member '%s' refers to type 0x%8.8llx which was unable to be parsed", 1606 MakeUserID(die->GetOffset()), 1607 name, 1608 encoding_uid); 1609 else 1610 GetObjectFile()->GetModule()->ReportError ("0x%8.8llx: DW_TAG_member refers to type 0x%8.8llx which was unable to be parsed", 1611 MakeUserID(die->GetOffset()), 1612 encoding_uid); 1613 } 1614 1615 if (member_byte_offset != UINT32_MAX || bit_size != 0) 1616 { 1617 ///////////////////////////////////////////////////////////// 1618 // How to locate a field given the DWARF debug information 1619 // 1620 // AT_byte_size indicates the size of the word in which the 1621 // bit offset must be interpreted. 1622 // 1623 // AT_data_member_location indicates the byte offset of the 1624 // word from the base address of the structure. 1625 // 1626 // AT_bit_offset indicates how many bits into the word 1627 // (according to the host endianness) the low-order bit of 1628 // the field starts. AT_bit_offset can be negative. 1629 // 1630 // AT_bit_size indicates the size of the field in bits. 1631 ///////////////////////////////////////////////////////////// 1632 1633 ByteOrder object_endian = GetObjectFile()->GetModule()->GetArchitecture().GetDefaultEndian(); 1634 1635 uint64_t total_bit_offset = 0; 1636 1637 total_bit_offset += (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8)); 1638 1639 if (object_endian == eByteOrderLittle) 1640 { 1641 total_bit_offset += byte_size * 8; 1642 total_bit_offset -= (bit_offset + bit_size); 1643 } 1644 else 1645 { 1646 total_bit_offset += bit_offset; 1647 } 1648 1649 layout_info.field_offsets.insert(std::make_pair(field_decl, total_bit_offset)); 1650 } 1651 if (prop_name != NULL) 1652 { 1653 1654 clang::ObjCIvarDecl *ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl); 1655 assert (ivar_decl != NULL); 1656 1657 1658 GetClangASTContext().AddObjCClassProperty (class_clang_type, 1659 prop_name, 1660 0, 1661 ivar_decl, 1662 prop_setter_name, 1663 prop_getter_name, 1664 prop_attributes); 1665 } 1666 } 1667 } 1668 ++member_idx; 1669 } 1670 break; 1671 1672 case DW_TAG_subprogram: 1673 // Let the type parsing code handle this one for us. 1674 member_function_dies.Append (die); 1675 break; 1676 1677 case DW_TAG_inheritance: 1678 { 1679 is_a_class = true; 1680 if (default_accessibility == eAccessNone) 1681 default_accessibility = eAccessPrivate; 1682 // TODO: implement DW_TAG_inheritance type parsing 1683 DWARFDebugInfoEntry::Attributes attributes; 1684 const size_t num_attributes = die->GetAttributes (this, 1685 dwarf_cu, 1686 fixed_form_sizes, 1687 attributes); 1688 if (num_attributes > 0) 1689 { 1690 Declaration decl; 1691 DWARFExpression location; 1692 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 1693 AccessType accessibility = default_accessibility; 1694 bool is_virtual = false; 1695 bool is_base_of_class = true; 1696 off_t member_offset = 0; 1697 uint32_t i; 1698 for (i=0; i<num_attributes; ++i) 1699 { 1700 const dw_attr_t attr = attributes.AttributeAtIndex(i); 1701 DWARFFormValue form_value; 1702 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 1703 { 1704 switch (attr) 1705 { 1706 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 1707 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 1708 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 1709 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 1710 case DW_AT_data_member_location: 1711 if (form_value.BlockData()) 1712 { 1713 Value initialValue(0); 1714 Value memberOffset(0); 1715 const DataExtractor& debug_info_data = get_debug_info_data(); 1716 uint32_t block_length = form_value.Unsigned(); 1717 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 1718 if (DWARFExpression::Evaluate (NULL, 1719 NULL, 1720 NULL, 1721 NULL, 1722 NULL, 1723 debug_info_data, 1724 block_offset, 1725 block_length, 1726 eRegisterKindDWARF, 1727 &initialValue, 1728 memberOffset, 1729 NULL)) 1730 { 1731 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt(); 1732 } 1733 } 1734 break; 1735 1736 case DW_AT_accessibility: 1737 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); 1738 break; 1739 1740 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break; 1741 default: 1742 case DW_AT_sibling: 1743 break; 1744 } 1745 } 1746 } 1747 1748 Type *base_class_type = ResolveTypeUID(encoding_uid); 1749 assert(base_class_type); 1750 1751 clang_type_t base_class_clang_type = base_class_type->GetClangFullType(); 1752 assert (base_class_clang_type); 1753 if (class_language == eLanguageTypeObjC) 1754 { 1755 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type); 1756 } 1757 else 1758 { 1759 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type, 1760 accessibility, 1761 is_virtual, 1762 is_base_of_class)); 1763 } 1764 } 1765 } 1766 break; 1767 1768 default: 1769 break; 1770 } 1771 } 1772 return count; 1773} 1774 1775 1776clang::DeclContext* 1777SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid) 1778{ 1779 DWARFDebugInfo* debug_info = DebugInfo(); 1780 if (debug_info && UserIDMatches(type_uid)) 1781 { 1782 DWARFCompileUnitSP cu_sp; 1783 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp); 1784 if (die) 1785 return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL); 1786 } 1787 return NULL; 1788} 1789 1790clang::DeclContext* 1791SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid) 1792{ 1793 if (UserIDMatches(type_uid)) 1794 return GetClangDeclContextForDIEOffset (sc, type_uid); 1795 return NULL; 1796} 1797 1798Type* 1799SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid) 1800{ 1801 if (UserIDMatches(type_uid)) 1802 { 1803 DWARFDebugInfo* debug_info = DebugInfo(); 1804 if (debug_info) 1805 { 1806 DWARFCompileUnitSP cu_sp; 1807 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp); 1808 const bool assert_not_being_parsed = true; 1809 return ResolveTypeUID (cu_sp.get(), type_die, assert_not_being_parsed); 1810 } 1811 } 1812 return NULL; 1813} 1814 1815Type* 1816SymbolFileDWARF::ResolveTypeUID (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* die, bool assert_not_being_parsed) 1817{ 1818 if (die != NULL) 1819 { 1820 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); 1821 if (log) 1822 GetObjectFile()->GetModule()->LogMessage (log.get(), 1823 "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'", 1824 die->GetOffset(), 1825 DW_TAG_value_to_name(die->Tag()), 1826 die->GetName(this, cu)); 1827 1828 // We might be coming in in the middle of a type tree (a class 1829 // withing a class, an enum within a class), so parse any needed 1830 // parent DIEs before we get to this one... 1831 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die); 1832 switch (decl_ctx_die->Tag()) 1833 { 1834 case DW_TAG_structure_type: 1835 case DW_TAG_union_type: 1836 case DW_TAG_class_type: 1837 { 1838 // Get the type, which could be a forward declaration 1839 if (log) 1840 GetObjectFile()->GetModule()->LogMessage (log.get(), 1841 "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x", 1842 die->GetOffset(), 1843 DW_TAG_value_to_name(die->Tag()), 1844 die->GetName(this, cu), 1845 decl_ctx_die->GetOffset()); 1846 1847 Type *parent_type = ResolveTypeUID (cu, decl_ctx_die, assert_not_being_parsed); 1848 if (child_requires_parent_class_union_or_struct_to_be_completed(die->Tag())) 1849 { 1850 if (log) 1851 GetObjectFile()->GetModule()->LogMessage (log.get(), 1852 "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent full type for 0x%8.8x since die is a function", 1853 die->GetOffset(), 1854 DW_TAG_value_to_name(die->Tag()), 1855 die->GetName(this, cu), 1856 decl_ctx_die->GetOffset()); 1857 // Ask the type to complete itself if it already hasn't since if we 1858 // want a function (method or static) from a class, the class must 1859 // create itself and add it's own methods and class functions. 1860 if (parent_type) 1861 parent_type->GetClangFullType(); 1862 } 1863 } 1864 break; 1865 1866 default: 1867 break; 1868 } 1869 return ResolveType (cu, die); 1870 } 1871 return NULL; 1872} 1873 1874// This function is used when SymbolFileDWARFDebugMap owns a bunch of 1875// SymbolFileDWARF objects to detect if this DWARF file is the one that 1876// can resolve a clang_type. 1877bool 1878SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type) 1879{ 1880 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type); 1881 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers); 1882 return die != NULL; 1883} 1884 1885 1886lldb::clang_type_t 1887SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type) 1888{ 1889 // We have a struct/union/class/enum that needs to be fully resolved. 1890 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type); 1891 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers); 1892 if (die == NULL) 1893 { 1894 // We have already resolved this type... 1895 return clang_type; 1896 } 1897 // Once we start resolving this type, remove it from the forward declaration 1898 // map in case anyone child members or other types require this type to get resolved. 1899 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition 1900 // are done. 1901 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers); 1902 1903 1904 // Disable external storage for this type so we don't get anymore 1905 // clang::ExternalASTSource queries for this type. 1906 ClangASTContext::SetHasExternalStorage (clang_type, false); 1907 1908 DWARFDebugInfo* debug_info = DebugInfo(); 1909 1910 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get(); 1911 Type *type = m_die_to_type.lookup (die); 1912 1913 const dw_tag_t tag = die->Tag(); 1914 1915 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); 1916 if (log) 1917 GetObjectFile()->GetModule()->LogMessage (log.get(), 1918 "0x%8.8llx: %s '%s' resolving forward declaration...\n", 1919 MakeUserID(die->GetOffset()), 1920 DW_TAG_value_to_name(tag), 1921 type->GetName().AsCString()); 1922 assert (clang_type); 1923 DWARFDebugInfoEntry::Attributes attributes; 1924 1925 ClangASTContext &ast = GetClangASTContext(); 1926 1927 switch (tag) 1928 { 1929 case DW_TAG_structure_type: 1930 case DW_TAG_union_type: 1931 case DW_TAG_class_type: 1932 { 1933 LayoutInfo layout_info; 1934 1935 ast.StartTagDeclarationDefinition (clang_type); 1936 { 1937 if (die->HasChildren()) 1938 { 1939 1940 LanguageType class_language = eLanguageTypeUnknown; 1941 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type); 1942 if (is_objc_class) 1943 class_language = eLanguageTypeObjC; 1944 1945 int tag_decl_kind = -1; 1946 AccessType default_accessibility = eAccessNone; 1947 if (tag == DW_TAG_structure_type) 1948 { 1949 tag_decl_kind = clang::TTK_Struct; 1950 default_accessibility = eAccessPublic; 1951 } 1952 else if (tag == DW_TAG_union_type) 1953 { 1954 tag_decl_kind = clang::TTK_Union; 1955 default_accessibility = eAccessPublic; 1956 } 1957 else if (tag == DW_TAG_class_type) 1958 { 1959 tag_decl_kind = clang::TTK_Class; 1960 default_accessibility = eAccessPrivate; 1961 } 1962 1963 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu)); 1964 std::vector<clang::CXXBaseSpecifier *> base_classes; 1965 std::vector<int> member_accessibilities; 1966 bool is_a_class = false; 1967 // Parse members and base classes first 1968 DWARFDIECollection member_function_dies; 1969 1970 ParseChildMembers (sc, 1971 curr_cu, 1972 die, 1973 clang_type, 1974 class_language, 1975 base_classes, 1976 member_accessibilities, 1977 member_function_dies, 1978 default_accessibility, 1979 is_a_class, 1980 layout_info); 1981 1982 // Now parse any methods if there were any... 1983 size_t num_functions = member_function_dies.Size(); 1984 if (num_functions > 0) 1985 { 1986 for (size_t i=0; i<num_functions; ++i) 1987 { 1988 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i)); 1989 } 1990 } 1991 1992 if (class_language == eLanguageTypeObjC) 1993 { 1994 std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type)); 1995 if (!class_str.empty()) 1996 { 1997 1998 DIEArray method_die_offsets; 1999 if (m_using_apple_tables) 2000 { 2001 if (m_apple_objc_ap.get()) 2002 m_apple_objc_ap->FindByName(class_str.c_str(), method_die_offsets); 2003 } 2004 else 2005 { 2006 if (!m_indexed) 2007 Index (); 2008 2009 ConstString class_name (class_str.c_str()); 2010 m_objc_class_selectors_index.Find (class_name, method_die_offsets); 2011 } 2012 2013 if (!method_die_offsets.empty()) 2014 { 2015 DWARFDebugInfo* debug_info = DebugInfo(); 2016 2017 DWARFCompileUnit* method_cu = NULL; 2018 const size_t num_matches = method_die_offsets.size(); 2019 for (size_t i=0; i<num_matches; ++i) 2020 { 2021 const dw_offset_t die_offset = method_die_offsets[i]; 2022 DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu); 2023 2024 if (method_die) 2025 ResolveType (method_cu, method_die); 2026 else 2027 { 2028 if (m_using_apple_tables) 2029 { 2030 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_objc accelerator table had bad die 0x%8.8x for '%s')\n", 2031 die_offset, class_str.c_str()); 2032 } 2033 } 2034 } 2035 } 2036 } 2037 } 2038 2039 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we 2040 // need to tell the clang type it is actually a class. 2041 if (class_language != eLanguageTypeObjC) 2042 { 2043 if (is_a_class && tag_decl_kind != clang::TTK_Class) 2044 ast.SetTagTypeKind (clang_type, clang::TTK_Class); 2045 } 2046 2047 // Since DW_TAG_structure_type gets used for both classes 2048 // and structures, we may need to set any DW_TAG_member 2049 // fields to have a "private" access if none was specified. 2050 // When we parsed the child members we tracked that actual 2051 // accessibility value for each DW_TAG_member in the 2052 // "member_accessibilities" array. If the value for the 2053 // member is zero, then it was set to the "default_accessibility" 2054 // which for structs was "public". Below we correct this 2055 // by setting any fields to "private" that weren't correctly 2056 // set. 2057 if (is_a_class && !member_accessibilities.empty()) 2058 { 2059 // This is a class and all members that didn't have 2060 // their access specified are private. 2061 ast.SetDefaultAccessForRecordFields (clang_type, 2062 eAccessPrivate, 2063 &member_accessibilities.front(), 2064 member_accessibilities.size()); 2065 } 2066 2067 if (!base_classes.empty()) 2068 { 2069 ast.SetBaseClassesForClassType (clang_type, 2070 &base_classes.front(), 2071 base_classes.size()); 2072 2073 // Clang will copy each CXXBaseSpecifier in "base_classes" 2074 // so we have to free them all. 2075 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(), 2076 base_classes.size()); 2077 } 2078 } 2079 } 2080 2081 ast.BuildIndirectFields (clang_type); 2082 2083 ast.CompleteTagDeclarationDefinition (clang_type); 2084 2085 if (!layout_info.field_offsets.empty()) 2086 { 2087 if (type) 2088 layout_info.bit_size = type->GetByteSize() * 8; 2089 if (layout_info.bit_size == 0) 2090 layout_info.bit_size = die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_byte_size, 0) * 8; 2091 clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); 2092 const clang::RecordType *record_type = clang::dyn_cast<clang::RecordType>(qual_type.getTypePtr()); 2093 if (record_type) 2094 { 2095 const clang::RecordDecl *record_decl = record_type->getDecl(); 2096 2097 if (log) 2098 { 2099 GetObjectFile()->GetModule()->LogMessage (log.get(), 2100 "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) caching layout info for record_decl = %p, bit_size = %llu, alignment = %llu, field_offsets[%u], base_offsets[0], vbase_offsets[0])", 2101 clang_type, 2102 record_decl, 2103 layout_info.bit_size, 2104 layout_info.alignment, 2105 (uint32_t)layout_info.field_offsets.size()); 2106 2107 llvm::DenseMap <const clang::FieldDecl *, uint64_t>::const_iterator pos, end = layout_info.field_offsets.end(); 2108 for (pos = layout_info.field_offsets.begin(); pos != end; ++pos) 2109 { 2110 GetObjectFile()->GetModule()->LogMessage (log.get(), 2111 "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field = { bit_offset=%u, name='%s' }", 2112 clang_type, 2113 (uint32_t)pos->second, 2114 pos->first->getNameAsString().c_str()); 2115 } 2116 } 2117 m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info)); 2118 } 2119 } 2120 } 2121 2122 return clang_type; 2123 2124 case DW_TAG_enumeration_type: 2125 ast.StartTagDeclarationDefinition (clang_type); 2126 if (die->HasChildren()) 2127 { 2128 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu)); 2129 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die); 2130 } 2131 ast.CompleteTagDeclarationDefinition (clang_type); 2132 return clang_type; 2133 2134 default: 2135 assert(false && "not a forward clang type decl!"); 2136 break; 2137 } 2138 return NULL; 2139} 2140 2141Type* 2142SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed) 2143{ 2144 if (type_die != NULL) 2145 { 2146 Type *type = m_die_to_type.lookup (type_die); 2147 2148 if (type == NULL) 2149 type = GetTypeForDIE (curr_cu, type_die).get(); 2150 2151 if (assert_not_being_parsed) 2152 { 2153 if (type != DIE_IS_BEING_PARSED) 2154 return type; 2155 2156 GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s", 2157 type_die->GetOffset(), 2158 DW_TAG_value_to_name(type_die->Tag()), 2159 type_die->GetName(this, curr_cu)); 2160 2161 } 2162 else 2163 return type; 2164 } 2165 return NULL; 2166} 2167 2168CompileUnit* 2169SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx) 2170{ 2171 // Check if the symbol vendor already knows about this compile unit? 2172 if (curr_cu->GetUserData() == NULL) 2173 { 2174 // The symbol vendor doesn't know about this compile unit, we 2175 // need to parse and add it to the symbol vendor object. 2176 CompUnitSP dc_cu; 2177 ParseCompileUnit(curr_cu, dc_cu); 2178 if (dc_cu.get()) 2179 { 2180 // Figure out the compile unit index if we weren't given one 2181 if (cu_idx == UINT32_MAX) 2182 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx); 2183 2184 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx); 2185 2186 if (m_debug_map_symfile) 2187 m_debug_map_symfile->SetCompileUnit(this, dc_cu); 2188 } 2189 } 2190 return (CompileUnit*)curr_cu->GetUserData(); 2191} 2192 2193bool 2194SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc) 2195{ 2196 sc.Clear(); 2197 // Check if the symbol vendor already knows about this compile unit? 2198 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX); 2199 2200 sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(func_die->GetOffset())).get(); 2201 if (sc.function == NULL) 2202 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die); 2203 2204 if (sc.function) 2205 { 2206 sc.module_sp = sc.function->CalculateSymbolContextModule(); 2207 return true; 2208 } 2209 2210 return false; 2211} 2212 2213uint32_t 2214SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 2215{ 2216 Timer scoped_timer(__PRETTY_FUNCTION__, 2217 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)", 2218 so_addr.GetSection().get(), 2219 so_addr.GetOffset(), 2220 resolve_scope); 2221 uint32_t resolved = 0; 2222 if (resolve_scope & ( eSymbolContextCompUnit | 2223 eSymbolContextFunction | 2224 eSymbolContextBlock | 2225 eSymbolContextLineEntry)) 2226 { 2227 lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); 2228 2229 DWARFDebugInfo* debug_info = DebugInfo(); 2230 if (debug_info) 2231 { 2232 dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr); 2233 if (cu_offset != DW_INVALID_OFFSET) 2234 { 2235 uint32_t cu_idx; 2236 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get(); 2237 if (curr_cu) 2238 { 2239 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx); 2240 assert(sc.comp_unit != NULL); 2241 resolved |= eSymbolContextCompUnit; 2242 2243 if (resolve_scope & eSymbolContextLineEntry) 2244 { 2245 LineTable *line_table = sc.comp_unit->GetLineTable(); 2246 if (line_table != NULL) 2247 { 2248 if (so_addr.IsLinkedAddress()) 2249 { 2250 Address linked_addr (so_addr); 2251 linked_addr.ResolveLinkedAddress(); 2252 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry)) 2253 { 2254 resolved |= eSymbolContextLineEntry; 2255 } 2256 } 2257 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry)) 2258 { 2259 resolved |= eSymbolContextLineEntry; 2260 } 2261 } 2262 } 2263 2264 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 2265 { 2266 DWARFDebugInfoEntry *function_die = NULL; 2267 DWARFDebugInfoEntry *block_die = NULL; 2268 if (resolve_scope & eSymbolContextBlock) 2269 { 2270 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die); 2271 } 2272 else 2273 { 2274 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL); 2275 } 2276 2277 if (function_die != NULL) 2278 { 2279 sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get(); 2280 if (sc.function == NULL) 2281 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die); 2282 } 2283 2284 if (sc.function != NULL) 2285 { 2286 resolved |= eSymbolContextFunction; 2287 2288 if (resolve_scope & eSymbolContextBlock) 2289 { 2290 Block& block = sc.function->GetBlock (true); 2291 2292 if (block_die != NULL) 2293 sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset())); 2294 else 2295 sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset())); 2296 if (sc.block) 2297 resolved |= eSymbolContextBlock; 2298 } 2299 } 2300 } 2301 } 2302 } 2303 } 2304 } 2305 return resolved; 2306} 2307 2308 2309 2310uint32_t 2311SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 2312{ 2313 const uint32_t prev_size = sc_list.GetSize(); 2314 if (resolve_scope & eSymbolContextCompUnit) 2315 { 2316 DWARFDebugInfo* debug_info = DebugInfo(); 2317 if (debug_info) 2318 { 2319 uint32_t cu_idx; 2320 DWARFCompileUnit* curr_cu = NULL; 2321 2322 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx) 2323 { 2324 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx); 2325 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0; 2326 if (check_inlines || file_spec_matches_cu_file_spec) 2327 { 2328 SymbolContext sc (m_obj_file->GetModule()); 2329 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx); 2330 assert(sc.comp_unit != NULL); 2331 2332 uint32_t file_idx = UINT32_MAX; 2333 2334 // If we are looking for inline functions only and we don't 2335 // find it in the support files, we are done. 2336 if (check_inlines) 2337 { 2338 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true); 2339 if (file_idx == UINT32_MAX) 2340 continue; 2341 } 2342 2343 if (line != 0) 2344 { 2345 LineTable *line_table = sc.comp_unit->GetLineTable(); 2346 2347 if (line_table != NULL && line != 0) 2348 { 2349 // We will have already looked up the file index if 2350 // we are searching for inline entries. 2351 if (!check_inlines) 2352 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true); 2353 2354 if (file_idx != UINT32_MAX) 2355 { 2356 uint32_t found_line; 2357 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry); 2358 found_line = sc.line_entry.line; 2359 2360 while (line_idx != UINT32_MAX) 2361 { 2362 sc.function = NULL; 2363 sc.block = NULL; 2364 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 2365 { 2366 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress(); 2367 if (file_vm_addr != LLDB_INVALID_ADDRESS) 2368 { 2369 DWARFDebugInfoEntry *function_die = NULL; 2370 DWARFDebugInfoEntry *block_die = NULL; 2371 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL); 2372 2373 if (function_die != NULL) 2374 { 2375 sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get(); 2376 if (sc.function == NULL) 2377 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die); 2378 } 2379 2380 if (sc.function != NULL) 2381 { 2382 Block& block = sc.function->GetBlock (true); 2383 2384 if (block_die != NULL) 2385 sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset())); 2386 else 2387 sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset())); 2388 } 2389 } 2390 } 2391 2392 sc_list.Append(sc); 2393 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry); 2394 } 2395 } 2396 } 2397 else if (file_spec_matches_cu_file_spec && !check_inlines) 2398 { 2399 // only append the context if we aren't looking for inline call sites 2400 // by file and line and if the file spec matches that of the compile unit 2401 sc_list.Append(sc); 2402 } 2403 } 2404 else if (file_spec_matches_cu_file_spec && !check_inlines) 2405 { 2406 // only append the context if we aren't looking for inline call sites 2407 // by file and line and if the file spec matches that of the compile unit 2408 sc_list.Append(sc); 2409 } 2410 2411 if (!check_inlines) 2412 break; 2413 } 2414 } 2415 } 2416 } 2417 return sc_list.GetSize() - prev_size; 2418} 2419 2420void 2421SymbolFileDWARF::Index () 2422{ 2423 if (m_indexed) 2424 return; 2425 m_indexed = true; 2426 Timer scoped_timer (__PRETTY_FUNCTION__, 2427 "SymbolFileDWARF::Index (%s)", 2428 GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 2429 2430 DWARFDebugInfo* debug_info = DebugInfo(); 2431 if (debug_info) 2432 { 2433 uint32_t cu_idx = 0; 2434 const uint32_t num_compile_units = GetNumCompileUnits(); 2435 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) 2436 { 2437 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx); 2438 2439 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1; 2440 2441 curr_cu->Index (cu_idx, 2442 m_function_basename_index, 2443 m_function_fullname_index, 2444 m_function_method_index, 2445 m_function_selector_index, 2446 m_objc_class_selectors_index, 2447 m_global_index, 2448 m_type_index, 2449 m_namespace_index); 2450 2451 // Keep memory down by clearing DIEs if this generate function 2452 // caused them to be parsed 2453 if (clear_dies) 2454 curr_cu->ClearDIEs (true); 2455 } 2456 2457 m_function_basename_index.Finalize(); 2458 m_function_fullname_index.Finalize(); 2459 m_function_method_index.Finalize(); 2460 m_function_selector_index.Finalize(); 2461 m_objc_class_selectors_index.Finalize(); 2462 m_global_index.Finalize(); 2463 m_type_index.Finalize(); 2464 m_namespace_index.Finalize(); 2465 2466#if defined (ENABLE_DEBUG_PRINTF) 2467 StreamFile s(stdout, false); 2468 s.Printf ("DWARF index for '%s/%s':", 2469 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(), 2470 GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 2471 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s); 2472 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s); 2473 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s); 2474 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s); 2475 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s); 2476 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s); 2477 s.Printf("\nTypes:\n"); m_type_index.Dump (&s); 2478 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s); 2479#endif 2480 } 2481} 2482 2483bool 2484SymbolFileDWARF::NamespaceDeclMatchesThisSymbolFile (const ClangNamespaceDecl *namespace_decl) 2485{ 2486 if (namespace_decl == NULL) 2487 { 2488 // Invalid namespace decl which means we aren't matching only things 2489 // in this symbol file, so return true to indicate it matches this 2490 // symbol file. 2491 return true; 2492 } 2493 2494 clang::ASTContext *namespace_ast = namespace_decl->GetASTContext(); 2495 2496 if (namespace_ast == NULL) 2497 return true; // No AST in the "namespace_decl", return true since it 2498 // could then match any symbol file, including this one 2499 2500 if (namespace_ast == GetClangASTContext().getASTContext()) 2501 return true; // The ASTs match, return true 2502 2503 // The namespace AST was valid, and it does not match... 2504 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2505 2506 if (log) 2507 GetObjectFile()->GetModule()->LogMessage(log.get(), "Valid namespace does not match symbol file"); 2508 2509 return false; 2510} 2511 2512bool 2513SymbolFileDWARF::DIEIsInNamespace (const ClangNamespaceDecl *namespace_decl, 2514 DWARFCompileUnit* cu, 2515 const DWARFDebugInfoEntry* die) 2516{ 2517 // No namespace specified, so the answesr i 2518 if (namespace_decl == NULL) 2519 return true; 2520 2521 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2522 2523 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die); 2524 if (decl_ctx_die) 2525 { 2526 2527 clang::NamespaceDecl *clang_namespace_decl = namespace_decl->GetNamespaceDecl(); 2528 if (clang_namespace_decl) 2529 { 2530 if (decl_ctx_die->Tag() != DW_TAG_namespace) 2531 { 2532 if (log) 2533 GetObjectFile()->GetModule()->LogMessage(log.get(), "Found a match, but its parent is not a namespace"); 2534 return false; 2535 } 2536 2537 DeclContextToDIEMap::iterator pos = m_decl_ctx_to_die.find(clang_namespace_decl); 2538 2539 if (pos == m_decl_ctx_to_die.end()) 2540 { 2541 if (log) 2542 GetObjectFile()->GetModule()->LogMessage(log.get(), "Found a match in a namespace, but its parent is not the requested namespace"); 2543 2544 return false; 2545 } 2546 2547 return pos->second.count (decl_ctx_die); 2548 } 2549 else 2550 { 2551 // We have a namespace_decl that was not NULL but it contained 2552 // a NULL "clang::NamespaceDecl", so this means the global namespace 2553 // So as long the the contained decl context DIE isn't a namespace 2554 // we should be ok. 2555 if (decl_ctx_die->Tag() != DW_TAG_namespace) 2556 return true; 2557 } 2558 } 2559 2560 if (log) 2561 GetObjectFile()->GetModule()->LogMessage(log.get(), "Found a match, but its parent doesn't exist"); 2562 2563 return false; 2564} 2565uint32_t 2566SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables) 2567{ 2568 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2569 2570 if (log) 2571 { 2572 GetObjectFile()->GetModule()->LogMessage (log.get(), 2573 "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", namespace_decl=%p, append=%u, max_matches=%u, variables)", 2574 name.GetCString(), 2575 namespace_decl, 2576 append, 2577 max_matches); 2578 } 2579 2580 if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl)) 2581 return 0; 2582 2583 DWARFDebugInfo* info = DebugInfo(); 2584 if (info == NULL) 2585 return 0; 2586 2587 // If we aren't appending the results to this list, then clear the list 2588 if (!append) 2589 variables.Clear(); 2590 2591 // Remember how many variables are in the list before we search in case 2592 // we are appending the results to a variable list. 2593 const uint32_t original_size = variables.GetSize(); 2594 2595 DIEArray die_offsets; 2596 2597 if (m_using_apple_tables) 2598 { 2599 if (m_apple_names_ap.get()) 2600 { 2601 const char *name_cstr = name.GetCString(); 2602 const char *base_name_start; 2603 const char *base_name_end = NULL; 2604 2605 if (!CPPLanguageRuntime::StripNamespacesFromVariableName(name_cstr, base_name_start, base_name_end)) 2606 base_name_start = name_cstr; 2607 2608 m_apple_names_ap->FindByName (base_name_start, die_offsets); 2609 } 2610 } 2611 else 2612 { 2613 // Index the DWARF if we haven't already 2614 if (!m_indexed) 2615 Index (); 2616 2617 m_global_index.Find (name, die_offsets); 2618 } 2619 2620 const size_t num_matches = die_offsets.size(); 2621 if (num_matches) 2622 { 2623 SymbolContext sc; 2624 sc.module_sp = m_obj_file->GetModule(); 2625 assert (sc.module_sp); 2626 2627 DWARFDebugInfo* debug_info = DebugInfo(); 2628 DWARFCompileUnit* dwarf_cu = NULL; 2629 const DWARFDebugInfoEntry* die = NULL; 2630 for (size_t i=0; i<num_matches; ++i) 2631 { 2632 const dw_offset_t die_offset = die_offsets[i]; 2633 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); 2634 2635 if (die) 2636 { 2637 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX); 2638 assert(sc.comp_unit != NULL); 2639 2640 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die)) 2641 continue; 2642 2643 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables); 2644 2645 if (variables.GetSize() - original_size >= max_matches) 2646 break; 2647 } 2648 else 2649 { 2650 if (m_using_apple_tables) 2651 { 2652 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')\n", 2653 die_offset, name.GetCString()); 2654 } 2655 } 2656 } 2657 } 2658 2659 // Return the number of variable that were appended to the list 2660 return variables.GetSize() - original_size; 2661} 2662 2663uint32_t 2664SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 2665{ 2666 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2667 2668 if (log) 2669 { 2670 GetObjectFile()->GetModule()->LogMessage (log.get(), 2671 "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)", 2672 regex.GetText(), 2673 append, 2674 max_matches); 2675 } 2676 2677 DWARFDebugInfo* info = DebugInfo(); 2678 if (info == NULL) 2679 return 0; 2680 2681 // If we aren't appending the results to this list, then clear the list 2682 if (!append) 2683 variables.Clear(); 2684 2685 // Remember how many variables are in the list before we search in case 2686 // we are appending the results to a variable list. 2687 const uint32_t original_size = variables.GetSize(); 2688 2689 DIEArray die_offsets; 2690 2691 if (m_using_apple_tables) 2692 { 2693 if (m_apple_names_ap.get()) 2694 { 2695 DWARFMappedHash::DIEInfoArray hash_data_array; 2696 if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array)) 2697 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets); 2698 } 2699 } 2700 else 2701 { 2702 // Index the DWARF if we haven't already 2703 if (!m_indexed) 2704 Index (); 2705 2706 m_global_index.Find (regex, die_offsets); 2707 } 2708 2709 SymbolContext sc; 2710 sc.module_sp = m_obj_file->GetModule(); 2711 assert (sc.module_sp); 2712 2713 DWARFCompileUnit* dwarf_cu = NULL; 2714 const DWARFDebugInfoEntry* die = NULL; 2715 const size_t num_matches = die_offsets.size(); 2716 if (num_matches) 2717 { 2718 DWARFDebugInfo* debug_info = DebugInfo(); 2719 for (size_t i=0; i<num_matches; ++i) 2720 { 2721 const dw_offset_t die_offset = die_offsets[i]; 2722 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); 2723 2724 if (die) 2725 { 2726 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX); 2727 2728 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables); 2729 2730 if (variables.GetSize() - original_size >= max_matches) 2731 break; 2732 } 2733 else 2734 { 2735 if (m_using_apple_tables) 2736 { 2737 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for regex '%s')\n", 2738 die_offset, regex.GetText()); 2739 } 2740 } 2741 } 2742 } 2743 2744 // Return the number of variable that were appended to the list 2745 return variables.GetSize() - original_size; 2746} 2747 2748 2749bool 2750SymbolFileDWARF::ResolveFunction (dw_offset_t die_offset, 2751 DWARFCompileUnit *&dwarf_cu, 2752 SymbolContextList& sc_list) 2753{ 2754 const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); 2755 return ResolveFunction (dwarf_cu, die, sc_list); 2756} 2757 2758 2759bool 2760SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu, 2761 const DWARFDebugInfoEntry *die, 2762 SymbolContextList& sc_list) 2763{ 2764 SymbolContext sc; 2765 2766 if (die == NULL) 2767 return false; 2768 2769 // If we were passed a die that is not a function, just return false... 2770 if (die->Tag() != DW_TAG_subprogram && die->Tag() != DW_TAG_inlined_subroutine) 2771 return false; 2772 2773 const DWARFDebugInfoEntry* inlined_die = NULL; 2774 if (die->Tag() == DW_TAG_inlined_subroutine) 2775 { 2776 inlined_die = die; 2777 2778 while ((die = die->GetParent()) != NULL) 2779 { 2780 if (die->Tag() == DW_TAG_subprogram) 2781 break; 2782 } 2783 } 2784 assert (die->Tag() == DW_TAG_subprogram); 2785 if (GetFunction (cu, die, sc)) 2786 { 2787 Address addr; 2788 // Parse all blocks if needed 2789 if (inlined_die) 2790 { 2791 sc.block = sc.function->GetBlock (true).FindBlockByID (MakeUserID(inlined_die->GetOffset())); 2792 assert (sc.block != NULL); 2793 if (sc.block->GetStartAddress (addr) == false) 2794 addr.Clear(); 2795 } 2796 else 2797 { 2798 sc.block = NULL; 2799 addr = sc.function->GetAddressRange().GetBaseAddress(); 2800 } 2801 2802 if (addr.IsValid()) 2803 { 2804 sc_list.Append(sc); 2805 return true; 2806 } 2807 } 2808 2809 return false; 2810} 2811 2812void 2813SymbolFileDWARF::FindFunctions (const ConstString &name, 2814 const NameToDIE &name_to_die, 2815 SymbolContextList& sc_list) 2816{ 2817 DIEArray die_offsets; 2818 if (name_to_die.Find (name, die_offsets)) 2819 { 2820 ParseFunctions (die_offsets, sc_list); 2821 } 2822} 2823 2824 2825void 2826SymbolFileDWARF::FindFunctions (const RegularExpression ®ex, 2827 const NameToDIE &name_to_die, 2828 SymbolContextList& sc_list) 2829{ 2830 DIEArray die_offsets; 2831 if (name_to_die.Find (regex, die_offsets)) 2832 { 2833 ParseFunctions (die_offsets, sc_list); 2834 } 2835} 2836 2837 2838void 2839SymbolFileDWARF::FindFunctions (const RegularExpression ®ex, 2840 const DWARFMappedHash::MemoryTable &memory_table, 2841 SymbolContextList& sc_list) 2842{ 2843 DIEArray die_offsets; 2844 DWARFMappedHash::DIEInfoArray hash_data_array; 2845 if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array)) 2846 { 2847 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets); 2848 ParseFunctions (die_offsets, sc_list); 2849 } 2850} 2851 2852void 2853SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets, 2854 SymbolContextList& sc_list) 2855{ 2856 const size_t num_matches = die_offsets.size(); 2857 if (num_matches) 2858 { 2859 SymbolContext sc; 2860 2861 DWARFCompileUnit* dwarf_cu = NULL; 2862 for (size_t i=0; i<num_matches; ++i) 2863 { 2864 const dw_offset_t die_offset = die_offsets[i]; 2865 ResolveFunction (die_offset, dwarf_cu, sc_list); 2866 } 2867 } 2868} 2869 2870bool 2871SymbolFileDWARF::FunctionDieMatchesPartialName (const DWARFDebugInfoEntry* die, 2872 const DWARFCompileUnit *dwarf_cu, 2873 uint32_t name_type_mask, 2874 const char *partial_name, 2875 const char *base_name_start, 2876 const char *base_name_end) 2877{ 2878 // If we are looking only for methods, throw away all the ones that aren't in C++ classes: 2879 if (name_type_mask == eFunctionNameTypeMethod 2880 || name_type_mask == eFunctionNameTypeBase) 2881 { 2882 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIEOffset(die->GetOffset()); 2883 if (!containing_decl_ctx) 2884 return false; 2885 2886 bool is_cxx_method = DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()); 2887 2888 if (!is_cxx_method && name_type_mask == eFunctionNameTypeMethod) 2889 return false; 2890 if (is_cxx_method && name_type_mask == eFunctionNameTypeBase) 2891 return false; 2892 } 2893 2894 // Now we need to check whether the name we got back for this type matches the extra specifications 2895 // that were in the name we're looking up: 2896 if (base_name_start != partial_name || *base_name_end != '\0') 2897 { 2898 // First see if the stuff to the left matches the full name. To do that let's see if 2899 // we can pull out the mips linkage name attribute: 2900 2901 Mangled best_name; 2902 2903 DWARFDebugInfoEntry::Attributes attributes; 2904 die->GetAttributes(this, dwarf_cu, NULL, attributes); 2905 uint32_t idx = attributes.FindAttributeIndex(DW_AT_MIPS_linkage_name); 2906 if (idx != UINT32_MAX) 2907 { 2908 DWARFFormValue form_value; 2909 if (attributes.ExtractFormValueAtIndex(this, idx, form_value)) 2910 { 2911 const char *name = form_value.AsCString(&get_debug_str_data()); 2912 best_name.SetValue (name, true); 2913 } 2914 } 2915 if (best_name) 2916 { 2917 const char *demangled = best_name.GetDemangledName().GetCString(); 2918 if (demangled) 2919 { 2920 std::string name_no_parens(partial_name, base_name_end - partial_name); 2921 const char *partial_in_demangled = strstr (demangled, name_no_parens.c_str()); 2922 if (partial_in_demangled == NULL) 2923 return false; 2924 else 2925 { 2926 // Sort out the case where our name is something like "Process::Destroy" and the match is 2927 // "SBProcess::Destroy" - that shouldn't be a match. We should really always match on 2928 // namespace boundaries... 2929 2930 if (partial_name[0] == ':' && partial_name[1] == ':') 2931 { 2932 // The partial name was already on a namespace boundary so all matches are good. 2933 return true; 2934 } 2935 else if (partial_in_demangled == demangled) 2936 { 2937 // They both start the same, so this is an good match. 2938 return true; 2939 } 2940 else 2941 { 2942 if (partial_in_demangled - demangled == 1) 2943 { 2944 // Only one character difference, can't be a namespace boundary... 2945 return false; 2946 } 2947 else if (*(partial_in_demangled - 1) == ':' && *(partial_in_demangled - 2) == ':') 2948 { 2949 // We are on a namespace boundary, so this is also good. 2950 return true; 2951 } 2952 else 2953 return false; 2954 } 2955 } 2956 } 2957 } 2958 } 2959 2960 return true; 2961} 2962 2963uint32_t 2964SymbolFileDWARF::FindFunctions (const ConstString &name, 2965 const lldb_private::ClangNamespaceDecl *namespace_decl, 2966 uint32_t name_type_mask, 2967 bool include_inlines, 2968 bool append, 2969 SymbolContextList& sc_list) 2970{ 2971 Timer scoped_timer (__PRETTY_FUNCTION__, 2972 "SymbolFileDWARF::FindFunctions (name = '%s')", 2973 name.AsCString()); 2974 2975 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 2976 2977 if (log) 2978 { 2979 GetObjectFile()->GetModule()->LogMessage (log.get(), 2980 "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)", 2981 name.GetCString(), 2982 name_type_mask, 2983 append); 2984 } 2985 2986 // If we aren't appending the results to this list, then clear the list 2987 if (!append) 2988 sc_list.Clear(); 2989 2990 if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl)) 2991 return 0; 2992 2993 // If name is empty then we won't find anything. 2994 if (name.IsEmpty()) 2995 return 0; 2996 2997 // Remember how many sc_list are in the list before we search in case 2998 // we are appending the results to a variable list. 2999 3000 const uint32_t original_size = sc_list.GetSize(); 3001 3002 const char *name_cstr = name.GetCString(); 3003 uint32_t effective_name_type_mask = eFunctionNameTypeNone; 3004 const char *base_name_start = name_cstr; 3005 const char *base_name_end = name_cstr + strlen(name_cstr); 3006 3007 if (name_type_mask & eFunctionNameTypeAuto) 3008 { 3009 if (CPPLanguageRuntime::IsCPPMangledName (name_cstr)) 3010 effective_name_type_mask = eFunctionNameTypeFull; 3011 else if (ObjCLanguageRuntime::IsPossibleObjCMethodName (name_cstr)) 3012 effective_name_type_mask = eFunctionNameTypeFull; 3013 else 3014 { 3015 if (ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr)) 3016 effective_name_type_mask |= eFunctionNameTypeSelector; 3017 3018 if (CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end)) 3019 effective_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase); 3020 } 3021 } 3022 else 3023 { 3024 effective_name_type_mask = name_type_mask; 3025 if (effective_name_type_mask & eFunctionNameTypeMethod || name_type_mask & eFunctionNameTypeBase) 3026 { 3027 // If they've asked for a CPP method or function name and it can't be that, we don't 3028 // even need to search for CPP methods or names. 3029 if (!CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end)) 3030 { 3031 effective_name_type_mask &= ~(eFunctionNameTypeMethod | eFunctionNameTypeBase); 3032 if (effective_name_type_mask == eFunctionNameTypeNone) 3033 return 0; 3034 } 3035 } 3036 3037 if (effective_name_type_mask & eFunctionNameTypeSelector) 3038 { 3039 if (!ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr)) 3040 { 3041 effective_name_type_mask &= ~(eFunctionNameTypeSelector); 3042 if (effective_name_type_mask == eFunctionNameTypeNone) 3043 return 0; 3044 } 3045 } 3046 } 3047 3048 DWARFDebugInfo* info = DebugInfo(); 3049 if (info == NULL) 3050 return 0; 3051 3052 DWARFCompileUnit *dwarf_cu = NULL; 3053 if (m_using_apple_tables) 3054 { 3055 if (m_apple_names_ap.get()) 3056 { 3057 3058 DIEArray die_offsets; 3059 3060 uint32_t num_matches = 0; 3061 3062 if (effective_name_type_mask & eFunctionNameTypeFull) 3063 { 3064 // If they asked for the full name, match what they typed. At some point we may 3065 // want to canonicalize this (strip double spaces, etc. For now, we just add all the 3066 // dies that we find by exact match. 3067 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets); 3068 for (uint32_t i = 0; i < num_matches; i++) 3069 { 3070 const dw_offset_t die_offset = die_offsets[i]; 3071 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); 3072 if (die) 3073 { 3074 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die)) 3075 continue; 3076 3077 if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine) 3078 continue; 3079 3080 ResolveFunction (dwarf_cu, die, sc_list); 3081 } 3082 else 3083 { 3084 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')", 3085 die_offset, name_cstr); 3086 } 3087 } 3088 } 3089 else 3090 { 3091 if (effective_name_type_mask & eFunctionNameTypeSelector) 3092 { 3093 if (namespace_decl && *namespace_decl) 3094 return 0; // no selectors in namespaces 3095 3096 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets); 3097 // Now make sure these are actually ObjC methods. In this case we can simply look up the name, 3098 // and if it is an ObjC method name, we're good. 3099 3100 for (uint32_t i = 0; i < num_matches; i++) 3101 { 3102 const dw_offset_t die_offset = die_offsets[i]; 3103 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); 3104 if (die) 3105 { 3106 const char *die_name = die->GetName(this, dwarf_cu); 3107 if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name)) 3108 { 3109 if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine) 3110 continue; 3111 3112 ResolveFunction (dwarf_cu, die, sc_list); 3113 } 3114 } 3115 else 3116 { 3117 GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')", 3118 die_offset, name_cstr); 3119 } 3120 } 3121 die_offsets.clear(); 3122 } 3123 3124 if (effective_name_type_mask & eFunctionNameTypeMethod 3125 || effective_name_type_mask & eFunctionNameTypeBase) 3126 { 3127 if ((effective_name_type_mask & eFunctionNameTypeMethod) && 3128 (namespace_decl && *namespace_decl)) 3129 return 0; // no methods in namespaces 3130 3131 // The apple_names table stores just the "base name" of C++ methods in the table. So we have to 3132 // extract the base name, look that up, and if there is any other information in the name we were 3133 // passed in we have to post-filter based on that. 3134 3135 // FIXME: Arrange the logic above so that we don't calculate the base name twice: 3136 std::string base_name(base_name_start, base_name_end - base_name_start); 3137 num_matches = m_apple_names_ap->FindByName (base_name.c_str(), die_offsets); 3138 3139 for (uint32_t i = 0; i < num_matches; i++) 3140 { 3141 const dw_offset_t die_offset = die_offsets[i]; 3142 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); 3143 if (die) 3144 { 3145 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die)) 3146 continue; 3147 3148 if (!FunctionDieMatchesPartialName(die, 3149 dwarf_cu, 3150 effective_name_type_mask, 3151 name_cstr, 3152 base_name_start, 3153 base_name_end)) 3154 continue; 3155 3156 if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine) 3157 continue; 3158 3159 // If we get to here, the die is good, and we should add it: 3160 ResolveFunction (dwarf_cu, die, sc_list); 3161 } 3162 else 3163 { 3164 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')", 3165 die_offset, name_cstr); 3166 } 3167 } 3168 die_offsets.clear(); 3169 } 3170 } 3171 } 3172 } 3173 else 3174 { 3175 3176 // Index the DWARF if we haven't already 3177 if (!m_indexed) 3178 Index (); 3179 3180 if (name_type_mask & eFunctionNameTypeFull) 3181 FindFunctions (name, m_function_fullname_index, sc_list); 3182 3183 std::string base_name(base_name_start, base_name_end - base_name_start); 3184 ConstString base_name_const(base_name.c_str()); 3185 DIEArray die_offsets; 3186 DWARFCompileUnit *dwarf_cu = NULL; 3187 3188 if (effective_name_type_mask & eFunctionNameTypeBase) 3189 { 3190 uint32_t num_base = m_function_basename_index.Find(base_name_const, die_offsets); 3191 for (uint32_t i = 0; i < num_base; i++) 3192 { 3193 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu); 3194 if (die) 3195 { 3196 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die)) 3197 continue; 3198 3199 if (!FunctionDieMatchesPartialName(die, 3200 dwarf_cu, 3201 effective_name_type_mask, 3202 name_cstr, 3203 base_name_start, 3204 base_name_end)) 3205 continue; 3206 3207 if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine) 3208 continue; 3209 3210 // If we get to here, the die is good, and we should add it: 3211 ResolveFunction (dwarf_cu, die, sc_list); 3212 } 3213 } 3214 die_offsets.clear(); 3215 } 3216 3217 if (effective_name_type_mask & eFunctionNameTypeMethod) 3218 { 3219 if (namespace_decl && *namespace_decl) 3220 return 0; // no methods in namespaces 3221 3222 uint32_t num_base = m_function_method_index.Find(base_name_const, die_offsets); 3223 { 3224 for (uint32_t i = 0; i < num_base; i++) 3225 { 3226 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu); 3227 if (die) 3228 { 3229 if (!FunctionDieMatchesPartialName(die, 3230 dwarf_cu, 3231 effective_name_type_mask, 3232 name_cstr, 3233 base_name_start, 3234 base_name_end)) 3235 continue; 3236 3237 if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine) 3238 continue; 3239 3240 // If we get to here, the die is good, and we should add it: 3241 ResolveFunction (dwarf_cu, die, sc_list); 3242 } 3243 } 3244 } 3245 die_offsets.clear(); 3246 } 3247 3248 if ((effective_name_type_mask & eFunctionNameTypeSelector) && (!namespace_decl || !*namespace_decl)) 3249 { 3250 FindFunctions (name, m_function_selector_index, sc_list); 3251 } 3252 3253 } 3254 3255 // Return the number of variable that were appended to the list 3256 return sc_list.GetSize() - original_size; 3257} 3258 3259uint32_t 3260SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list) 3261{ 3262 Timer scoped_timer (__PRETTY_FUNCTION__, 3263 "SymbolFileDWARF::FindFunctions (regex = '%s')", 3264 regex.GetText()); 3265 3266 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 3267 3268 if (log) 3269 { 3270 GetObjectFile()->GetModule()->LogMessage (log.get(), 3271 "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)", 3272 regex.GetText(), 3273 append); 3274 } 3275 3276 3277 // If we aren't appending the results to this list, then clear the list 3278 if (!append) 3279 sc_list.Clear(); 3280 3281 // Remember how many sc_list are in the list before we search in case 3282 // we are appending the results to a variable list. 3283 uint32_t original_size = sc_list.GetSize(); 3284 3285 if (m_using_apple_tables) 3286 { 3287 if (m_apple_names_ap.get()) 3288 FindFunctions (regex, *m_apple_names_ap, sc_list); 3289 } 3290 else 3291 { 3292 // Index the DWARF if we haven't already 3293 if (!m_indexed) 3294 Index (); 3295 3296 FindFunctions (regex, m_function_basename_index, sc_list); 3297 3298 FindFunctions (regex, m_function_fullname_index, sc_list); 3299 } 3300 3301 // Return the number of variable that were appended to the list 3302 return sc_list.GetSize() - original_size; 3303} 3304 3305uint32_t 3306SymbolFileDWARF::FindTypes (const SymbolContext& sc, 3307 const ConstString &name, 3308 const lldb_private::ClangNamespaceDecl *namespace_decl, 3309 bool append, 3310 uint32_t max_matches, 3311 TypeList& types) 3312{ 3313 DWARFDebugInfo* info = DebugInfo(); 3314 if (info == NULL) 3315 return 0; 3316 3317 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 3318 3319 if (log) 3320 { 3321 GetObjectFile()->GetModule()->LogMessage (log.get(), 3322 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", append=%u, max_matches=%u, type_list)", 3323 name.GetCString(), 3324 append, 3325 max_matches); 3326 } 3327 3328 // If we aren't appending the results to this list, then clear the list 3329 if (!append) 3330 types.Clear(); 3331 3332 if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl)) 3333 return 0; 3334 3335 DIEArray die_offsets; 3336 3337 if (m_using_apple_tables) 3338 { 3339 if (m_apple_types_ap.get()) 3340 { 3341 const char *name_cstr = name.GetCString(); 3342 m_apple_types_ap->FindByName (name_cstr, die_offsets); 3343 } 3344 } 3345 else 3346 { 3347 if (!m_indexed) 3348 Index (); 3349 3350 m_type_index.Find (name, die_offsets); 3351 } 3352 3353 const size_t num_matches = die_offsets.size(); 3354 3355 if (num_matches) 3356 { 3357 const uint32_t initial_types_size = types.GetSize(); 3358 DWARFCompileUnit* dwarf_cu = NULL; 3359 const DWARFDebugInfoEntry* die = NULL; 3360 DWARFDebugInfo* debug_info = DebugInfo(); 3361 for (size_t i=0; i<num_matches; ++i) 3362 { 3363 const dw_offset_t die_offset = die_offsets[i]; 3364 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); 3365 3366 if (die) 3367 { 3368 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die)) 3369 continue; 3370 3371 Type *matching_type = ResolveType (dwarf_cu, die); 3372 if (matching_type) 3373 { 3374 // We found a type pointer, now find the shared pointer form our type list 3375 types.InsertUnique (matching_type->shared_from_this()); 3376 if (types.GetSize() >= max_matches) 3377 break; 3378 } 3379 } 3380 else 3381 { 3382 if (m_using_apple_tables) 3383 { 3384 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n", 3385 die_offset, name.GetCString()); 3386 } 3387 } 3388 3389 } 3390 return types.GetSize() - initial_types_size; 3391 } 3392 return 0; 3393} 3394 3395 3396ClangNamespaceDecl 3397SymbolFileDWARF::FindNamespace (const SymbolContext& sc, 3398 const ConstString &name, 3399 const lldb_private::ClangNamespaceDecl *parent_namespace_decl) 3400{ 3401 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); 3402 3403 if (log) 3404 { 3405 GetObjectFile()->GetModule()->LogMessage (log.get(), 3406 "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")", 3407 name.GetCString()); 3408 } 3409 3410 if (!NamespaceDeclMatchesThisSymbolFile(parent_namespace_decl)) 3411 return ClangNamespaceDecl(); 3412 3413 ClangNamespaceDecl namespace_decl; 3414 DWARFDebugInfo* info = DebugInfo(); 3415 if (info) 3416 { 3417 DIEArray die_offsets; 3418 3419 // Index if we already haven't to make sure the compile units 3420 // get indexed and make their global DIE index list 3421 if (m_using_apple_tables) 3422 { 3423 if (m_apple_namespaces_ap.get()) 3424 { 3425 const char *name_cstr = name.GetCString(); 3426 m_apple_namespaces_ap->FindByName (name_cstr, die_offsets); 3427 } 3428 } 3429 else 3430 { 3431 if (!m_indexed) 3432 Index (); 3433 3434 m_namespace_index.Find (name, die_offsets); 3435 } 3436 3437 DWARFCompileUnit* dwarf_cu = NULL; 3438 const DWARFDebugInfoEntry* die = NULL; 3439 const size_t num_matches = die_offsets.size(); 3440 if (num_matches) 3441 { 3442 DWARFDebugInfo* debug_info = DebugInfo(); 3443 for (size_t i=0; i<num_matches; ++i) 3444 { 3445 const dw_offset_t die_offset = die_offsets[i]; 3446 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); 3447 3448 if (die) 3449 { 3450 if (parent_namespace_decl && !DIEIsInNamespace (parent_namespace_decl, dwarf_cu, die)) 3451 continue; 3452 3453 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (dwarf_cu, die); 3454 if (clang_namespace_decl) 3455 { 3456 namespace_decl.SetASTContext (GetClangASTContext().getASTContext()); 3457 namespace_decl.SetNamespaceDecl (clang_namespace_decl); 3458 break; 3459 } 3460 } 3461 else 3462 { 3463 if (m_using_apple_tables) 3464 { 3465 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_namespaces accelerator table had bad die 0x%8.8x for '%s')\n", 3466 die_offset, name.GetCString()); 3467 } 3468 } 3469 3470 } 3471 } 3472 } 3473 return namespace_decl; 3474} 3475 3476uint32_t 3477SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types) 3478{ 3479 // Remember how many sc_list are in the list before we search in case 3480 // we are appending the results to a variable list. 3481 uint32_t original_size = types.GetSize(); 3482 3483 const uint32_t num_die_offsets = die_offsets.size(); 3484 // Parse all of the types we found from the pubtypes matches 3485 uint32_t i; 3486 uint32_t num_matches = 0; 3487 for (i = 0; i < num_die_offsets; ++i) 3488 { 3489 Type *matching_type = ResolveTypeUID (die_offsets[i]); 3490 if (matching_type) 3491 { 3492 // We found a type pointer, now find the shared pointer form our type list 3493 types.InsertUnique (matching_type->shared_from_this()); 3494 ++num_matches; 3495 if (num_matches >= max_matches) 3496 break; 3497 } 3498 } 3499 3500 // Return the number of variable that were appended to the list 3501 return types.GetSize() - original_size; 3502} 3503 3504 3505size_t 3506SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc, 3507 clang::DeclContext *containing_decl_ctx, 3508 DWARFCompileUnit* dwarf_cu, 3509 const DWARFDebugInfoEntry *parent_die, 3510 bool skip_artificial, 3511 bool &is_static, 3512 TypeList* type_list, 3513 std::vector<clang_type_t>& function_param_types, 3514 std::vector<clang::ParmVarDecl*>& function_param_decls, 3515 unsigned &type_quals, 3516 ClangASTContext::TemplateParameterInfos &template_param_infos) 3517{ 3518 if (parent_die == NULL) 3519 return 0; 3520 3521 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 3522 3523 size_t arg_idx = 0; 3524 const DWARFDebugInfoEntry *die; 3525 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 3526 { 3527 dw_tag_t tag = die->Tag(); 3528 switch (tag) 3529 { 3530 case DW_TAG_formal_parameter: 3531 { 3532 DWARFDebugInfoEntry::Attributes attributes; 3533 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 3534 if (num_attributes > 0) 3535 { 3536 const char *name = NULL; 3537 Declaration decl; 3538 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET; 3539 bool is_artificial = false; 3540 // one of None, Auto, Register, Extern, Static, PrivateExtern 3541 3542 clang::StorageClass storage = clang::SC_None; 3543 uint32_t i; 3544 for (i=0; i<num_attributes; ++i) 3545 { 3546 const dw_attr_t attr = attributes.AttributeAtIndex(i); 3547 DWARFFormValue form_value; 3548 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3549 { 3550 switch (attr) 3551 { 3552 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3553 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3554 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3555 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 3556 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break; 3557 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break; 3558 case DW_AT_location: 3559 // if (form_value.BlockData()) 3560 // { 3561 // const DataExtractor& debug_info_data = debug_info(); 3562 // uint32_t block_length = form_value.Unsigned(); 3563 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length); 3564 // } 3565 // else 3566 // { 3567 // } 3568 // break; 3569 case DW_AT_const_value: 3570 case DW_AT_default_value: 3571 case DW_AT_description: 3572 case DW_AT_endianity: 3573 case DW_AT_is_optional: 3574 case DW_AT_segment: 3575 case DW_AT_variable_parameter: 3576 default: 3577 case DW_AT_abstract_origin: 3578 case DW_AT_sibling: 3579 break; 3580 } 3581 } 3582 } 3583 3584 bool skip = false; 3585 if (skip_artificial) 3586 { 3587 if (is_artificial) 3588 { 3589 // In order to determine if a C++ member function is 3590 // "const" we have to look at the const-ness of "this"... 3591 // Ugly, but that 3592 if (arg_idx == 0) 3593 { 3594 if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind())) 3595 { 3596 // Often times compilers omit the "this" name for the 3597 // specification DIEs, so we can't rely upon the name 3598 // being in the formal parameter DIE... 3599 if (name == NULL || ::strcmp(name, "this")==0) 3600 { 3601 Type *this_type = ResolveTypeUID (param_type_die_offset); 3602 if (this_type) 3603 { 3604 uint32_t encoding_mask = this_type->GetEncodingMask(); 3605 if (encoding_mask & Type::eEncodingIsPointerUID) 3606 { 3607 is_static = false; 3608 3609 if (encoding_mask & (1u << Type::eEncodingIsConstUID)) 3610 type_quals |= clang::Qualifiers::Const; 3611 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID)) 3612 type_quals |= clang::Qualifiers::Volatile; 3613 } 3614 } 3615 } 3616 } 3617 } 3618 skip = true; 3619 } 3620 else 3621 { 3622 3623 // HACK: Objective C formal parameters "self" and "_cmd" 3624 // are not marked as artificial in the DWARF... 3625 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX); 3626 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus)) 3627 { 3628 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0)) 3629 skip = true; 3630 } 3631 } 3632 } 3633 3634 if (!skip) 3635 { 3636 Type *type = ResolveTypeUID(param_type_die_offset); 3637 if (type) 3638 { 3639 function_param_types.push_back (type->GetClangForwardType()); 3640 3641 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, 3642 type->GetClangForwardType(), 3643 storage); 3644 assert(param_var_decl); 3645 function_param_decls.push_back(param_var_decl); 3646 } 3647 } 3648 } 3649 arg_idx++; 3650 } 3651 break; 3652 3653 case DW_TAG_template_type_parameter: 3654 case DW_TAG_template_value_parameter: 3655 ParseTemplateDIE (dwarf_cu, die,template_param_infos); 3656 break; 3657 3658 default: 3659 break; 3660 } 3661 } 3662 return arg_idx; 3663} 3664 3665size_t 3666SymbolFileDWARF::ParseChildEnumerators 3667( 3668 const SymbolContext& sc, 3669 clang_type_t enumerator_clang_type, 3670 uint32_t enumerator_byte_size, 3671 DWARFCompileUnit* dwarf_cu, 3672 const DWARFDebugInfoEntry *parent_die 3673) 3674{ 3675 if (parent_die == NULL) 3676 return 0; 3677 3678 size_t enumerators_added = 0; 3679 const DWARFDebugInfoEntry *die; 3680 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 3681 3682 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 3683 { 3684 const dw_tag_t tag = die->Tag(); 3685 if (tag == DW_TAG_enumerator) 3686 { 3687 DWARFDebugInfoEntry::Attributes attributes; 3688 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 3689 if (num_child_attributes > 0) 3690 { 3691 const char *name = NULL; 3692 bool got_value = false; 3693 int64_t enum_value = 0; 3694 Declaration decl; 3695 3696 uint32_t i; 3697 for (i=0; i<num_child_attributes; ++i) 3698 { 3699 const dw_attr_t attr = attributes.AttributeAtIndex(i); 3700 DWARFFormValue form_value; 3701 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3702 { 3703 switch (attr) 3704 { 3705 case DW_AT_const_value: 3706 got_value = true; 3707 enum_value = form_value.Unsigned(); 3708 break; 3709 3710 case DW_AT_name: 3711 name = form_value.AsCString(&get_debug_str_data()); 3712 break; 3713 3714 case DW_AT_description: 3715 default: 3716 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3717 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3718 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3719 case DW_AT_sibling: 3720 break; 3721 } 3722 } 3723 } 3724 3725 if (name && name[0] && got_value) 3726 { 3727 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type, 3728 enumerator_clang_type, 3729 decl, 3730 name, 3731 enum_value, 3732 enumerator_byte_size * 8); 3733 ++enumerators_added; 3734 } 3735 } 3736 } 3737 } 3738 return enumerators_added; 3739} 3740 3741void 3742SymbolFileDWARF::ParseChildArrayInfo 3743( 3744 const SymbolContext& sc, 3745 DWARFCompileUnit* dwarf_cu, 3746 const DWARFDebugInfoEntry *parent_die, 3747 int64_t& first_index, 3748 std::vector<uint64_t>& element_orders, 3749 uint32_t& byte_stride, 3750 uint32_t& bit_stride 3751) 3752{ 3753 if (parent_die == NULL) 3754 return; 3755 3756 const DWARFDebugInfoEntry *die; 3757 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 3758 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 3759 { 3760 const dw_tag_t tag = die->Tag(); 3761 switch (tag) 3762 { 3763 case DW_TAG_enumerator: 3764 { 3765 DWARFDebugInfoEntry::Attributes attributes; 3766 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 3767 if (num_child_attributes > 0) 3768 { 3769 const char *name = NULL; 3770 bool got_value = false; 3771 int64_t enum_value = 0; 3772 3773 uint32_t i; 3774 for (i=0; i<num_child_attributes; ++i) 3775 { 3776 const dw_attr_t attr = attributes.AttributeAtIndex(i); 3777 DWARFFormValue form_value; 3778 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3779 { 3780 switch (attr) 3781 { 3782 case DW_AT_const_value: 3783 got_value = true; 3784 enum_value = form_value.Unsigned(); 3785 break; 3786 3787 case DW_AT_name: 3788 name = form_value.AsCString(&get_debug_str_data()); 3789 break; 3790 3791 case DW_AT_description: 3792 default: 3793 case DW_AT_decl_file: 3794 case DW_AT_decl_line: 3795 case DW_AT_decl_column: 3796 case DW_AT_sibling: 3797 break; 3798 } 3799 } 3800 } 3801 } 3802 } 3803 break; 3804 3805 case DW_TAG_subrange_type: 3806 { 3807 DWARFDebugInfoEntry::Attributes attributes; 3808 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 3809 if (num_child_attributes > 0) 3810 { 3811 const char *name = NULL; 3812 bool got_value = false; 3813 uint64_t byte_size = 0; 3814 int64_t enum_value = 0; 3815 uint64_t num_elements = 0; 3816 uint64_t lower_bound = 0; 3817 uint64_t upper_bound = 0; 3818 uint32_t i; 3819 for (i=0; i<num_child_attributes; ++i) 3820 { 3821 const dw_attr_t attr = attributes.AttributeAtIndex(i); 3822 DWARFFormValue form_value; 3823 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3824 { 3825 switch (attr) 3826 { 3827 case DW_AT_const_value: 3828 got_value = true; 3829 enum_value = form_value.Unsigned(); 3830 break; 3831 3832 case DW_AT_name: 3833 name = form_value.AsCString(&get_debug_str_data()); 3834 break; 3835 3836 case DW_AT_count: 3837 num_elements = form_value.Unsigned(); 3838 break; 3839 3840 case DW_AT_bit_stride: 3841 bit_stride = form_value.Unsigned(); 3842 break; 3843 3844 case DW_AT_byte_stride: 3845 byte_stride = form_value.Unsigned(); 3846 break; 3847 3848 case DW_AT_byte_size: 3849 byte_size = form_value.Unsigned(); 3850 break; 3851 3852 case DW_AT_lower_bound: 3853 lower_bound = form_value.Unsigned(); 3854 break; 3855 3856 case DW_AT_upper_bound: 3857 upper_bound = form_value.Unsigned(); 3858 break; 3859 3860 default: 3861 case DW_AT_abstract_origin: 3862 case DW_AT_accessibility: 3863 case DW_AT_allocated: 3864 case DW_AT_associated: 3865 case DW_AT_data_location: 3866 case DW_AT_declaration: 3867 case DW_AT_description: 3868 case DW_AT_sibling: 3869 case DW_AT_threads_scaled: 3870 case DW_AT_type: 3871 case DW_AT_visibility: 3872 break; 3873 } 3874 } 3875 } 3876 3877 if (upper_bound > lower_bound) 3878 num_elements = upper_bound - lower_bound + 1; 3879 3880 if (num_elements > 0) 3881 element_orders.push_back (num_elements); 3882 } 3883 } 3884 break; 3885 } 3886 } 3887} 3888 3889TypeSP 3890SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die) 3891{ 3892 TypeSP type_sp; 3893 if (die != NULL) 3894 { 3895 assert(curr_cu != NULL); 3896 Type *type_ptr = m_die_to_type.lookup (die); 3897 if (type_ptr == NULL) 3898 { 3899 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu); 3900 assert (lldb_cu); 3901 SymbolContext sc(lldb_cu); 3902 type_sp = ParseType(sc, curr_cu, die, NULL); 3903 } 3904 else if (type_ptr != DIE_IS_BEING_PARSED) 3905 { 3906 // Grab the existing type from the master types lists 3907 type_sp = type_ptr->shared_from_this(); 3908 } 3909 3910 } 3911 return type_sp; 3912} 3913 3914clang::DeclContext * 3915SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset) 3916{ 3917 if (die_offset != DW_INVALID_OFFSET) 3918 { 3919 DWARFCompileUnitSP cu_sp; 3920 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp); 3921 return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL); 3922 } 3923 return NULL; 3924} 3925 3926clang::DeclContext * 3927SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset) 3928{ 3929 if (die_offset != DW_INVALID_OFFSET) 3930 { 3931 DWARFDebugInfo* debug_info = DebugInfo(); 3932 if (debug_info) 3933 { 3934 DWARFCompileUnitSP cu_sp; 3935 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(die_offset, &cu_sp); 3936 if (die) 3937 return GetClangDeclContextForDIE (sc, cu_sp.get(), die); 3938 } 3939 } 3940 return NULL; 3941} 3942 3943clang::NamespaceDecl * 3944SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die) 3945{ 3946 if (die && die->Tag() == DW_TAG_namespace) 3947 { 3948 // See if we already parsed this namespace DIE and associated it with a 3949 // uniqued namespace declaration 3950 clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die]); 3951 if (namespace_decl) 3952 return namespace_decl; 3953 else 3954 { 3955 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL); 3956 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (curr_cu, die, NULL); 3957 namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, containing_decl_ctx); 3958 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); 3959 if (log) 3960 { 3961 if (namespace_name) 3962 { 3963 GetObjectFile()->GetModule()->LogMessage (log.get(), 3964 "ASTContext => %p: 0x%8.8llx: DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl *%p (original = %p)", 3965 GetClangASTContext().getASTContext(), 3966 MakeUserID(die->GetOffset()), 3967 namespace_name, 3968 namespace_decl, 3969 namespace_decl->getOriginalNamespace()); 3970 } 3971 else 3972 { 3973 GetObjectFile()->GetModule()->LogMessage (log.get(), 3974 "ASTContext => %p: 0x%8.8llx: DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p (original = %p)", 3975 GetClangASTContext().getASTContext(), 3976 MakeUserID(die->GetOffset()), 3977 namespace_decl, 3978 namespace_decl->getOriginalNamespace()); 3979 } 3980 } 3981 3982 if (namespace_decl) 3983 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die); 3984 return namespace_decl; 3985 } 3986 } 3987 return NULL; 3988} 3989 3990clang::DeclContext * 3991SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) 3992{ 3993 clang::DeclContext *clang_decl_ctx = GetCachedClangDeclContextForDIE (die); 3994 if (clang_decl_ctx) 3995 return clang_decl_ctx; 3996 // If this DIE has a specification, or an abstract origin, then trace to those. 3997 3998 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET); 3999 if (die_offset != DW_INVALID_OFFSET) 4000 return GetClangDeclContextForDIEOffset (sc, die_offset); 4001 4002 die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET); 4003 if (die_offset != DW_INVALID_OFFSET) 4004 return GetClangDeclContextForDIEOffset (sc, die_offset); 4005 4006 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); 4007 if (log) 4008 GetObjectFile()->GetModule()->LogMessage(log.get(), "SymbolFileDWARF::GetClangDeclContextForDIE (die = 0x%8.8x) %s '%s'", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), die->GetName(this, cu)); 4009 // This is the DIE we want. Parse it, then query our map. 4010 bool assert_not_being_parsed = true; 4011 ResolveTypeUID (cu, die, assert_not_being_parsed); 4012 4013 clang_decl_ctx = GetCachedClangDeclContextForDIE (die); 4014 4015 return clang_decl_ctx; 4016} 4017 4018clang::DeclContext * 4019SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die, const DWARFDebugInfoEntry **decl_ctx_die_copy) 4020{ 4021 if (m_clang_tu_decl == NULL) 4022 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl(); 4023 4024 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die); 4025 4026 if (decl_ctx_die_copy) 4027 *decl_ctx_die_copy = decl_ctx_die; 4028 4029 if (decl_ctx_die) 4030 { 4031 4032 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find (decl_ctx_die); 4033 if (pos != m_die_to_decl_ctx.end()) 4034 return pos->second; 4035 4036 switch (decl_ctx_die->Tag()) 4037 { 4038 case DW_TAG_compile_unit: 4039 return m_clang_tu_decl; 4040 4041 case DW_TAG_namespace: 4042 return ResolveNamespaceDIE (cu, decl_ctx_die); 4043 break; 4044 4045 case DW_TAG_structure_type: 4046 case DW_TAG_union_type: 4047 case DW_TAG_class_type: 4048 { 4049 Type* type = ResolveType (cu, decl_ctx_die); 4050 if (type) 4051 { 4052 clang::DeclContext *decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ()); 4053 if (decl_ctx) 4054 { 4055 LinkDeclContextToDIE (decl_ctx, decl_ctx_die); 4056 if (decl_ctx) 4057 return decl_ctx; 4058 } 4059 } 4060 } 4061 break; 4062 4063 default: 4064 break; 4065 } 4066 } 4067 return m_clang_tu_decl; 4068} 4069 4070 4071const DWARFDebugInfoEntry * 4072SymbolFileDWARF::GetDeclContextDIEContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die) 4073{ 4074 if (cu && die) 4075 { 4076 const DWARFDebugInfoEntry * const decl_die = die; 4077 4078 while (die != NULL) 4079 { 4080 // If this is the original DIE that we are searching for a declaration 4081 // for, then don't look in the cache as we don't want our own decl 4082 // context to be our decl context... 4083 if (decl_die != die) 4084 { 4085 switch (die->Tag()) 4086 { 4087 case DW_TAG_compile_unit: 4088 case DW_TAG_namespace: 4089 case DW_TAG_structure_type: 4090 case DW_TAG_union_type: 4091 case DW_TAG_class_type: 4092 return die; 4093 4094 default: 4095 break; 4096 } 4097 } 4098 4099 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET); 4100 if (die_offset != DW_INVALID_OFFSET) 4101 { 4102 DWARFCompileUnit *spec_cu = cu; 4103 const DWARFDebugInfoEntry *spec_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &spec_cu); 4104 const DWARFDebugInfoEntry *spec_die_decl_ctx_die = GetDeclContextDIEContainingDIE (spec_cu, spec_die); 4105 if (spec_die_decl_ctx_die) 4106 return spec_die_decl_ctx_die; 4107 } 4108 4109 die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET); 4110 if (die_offset != DW_INVALID_OFFSET) 4111 { 4112 DWARFCompileUnit *abs_cu = cu; 4113 const DWARFDebugInfoEntry *abs_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &abs_cu); 4114 const DWARFDebugInfoEntry *abs_die_decl_ctx_die = GetDeclContextDIEContainingDIE (abs_cu, abs_die); 4115 if (abs_die_decl_ctx_die) 4116 return abs_die_decl_ctx_die; 4117 } 4118 4119 die = die->GetParent(); 4120 } 4121 } 4122 return NULL; 4123} 4124 4125 4126Symbol * 4127SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name) 4128{ 4129 Symbol *objc_class_symbol = NULL; 4130 if (m_obj_file) 4131 { 4132 Symtab *symtab = m_obj_file->GetSymtab(); 4133 if (symtab) 4134 { 4135 objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name, 4136 eSymbolTypeObjCClass, 4137 Symtab::eDebugNo, 4138 Symtab::eVisibilityAny); 4139 } 4140 } 4141 return objc_class_symbol; 4142} 4143 4144// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If they don't 4145// then we can end up looking through all class types for a complete type and never find 4146// the full definition. We need to know if this attribute is supported, so we determine 4147// this here and cache th result. We also need to worry about the debug map DWARF file 4148// if we are doing darwin DWARF in .o file debugging. 4149bool 4150SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu) 4151{ 4152 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) 4153 { 4154 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo; 4155 if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type()) 4156 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; 4157 else 4158 { 4159 DWARFDebugInfo* debug_info = DebugInfo(); 4160 const uint32_t num_compile_units = GetNumCompileUnits(); 4161 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) 4162 { 4163 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx); 4164 if (curr_cu != cu && curr_cu->Supports_DW_AT_APPLE_objc_complete_type()) 4165 { 4166 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; 4167 break; 4168 } 4169 } 4170 } 4171 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && m_debug_map_symfile) 4172 return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this); 4173 } 4174 return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes; 4175} 4176 4177// This function can be used when a DIE is found that is a forward declaration 4178// DIE and we want to try and find a type that has the complete definition. 4179TypeSP 4180SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die, 4181 const ConstString &type_name, 4182 bool must_be_implementation) 4183{ 4184 4185 TypeSP type_sp; 4186 4187 if (!type_name || (must_be_implementation && !GetObjCClassSymbol (type_name))) 4188 return type_sp; 4189 4190 DIEArray die_offsets; 4191 4192 if (m_using_apple_tables) 4193 { 4194 if (m_apple_types_ap.get()) 4195 { 4196 const char *name_cstr = type_name.GetCString(); 4197 m_apple_types_ap->FindCompleteObjCClassByName (name_cstr, die_offsets, must_be_implementation); 4198 } 4199 } 4200 else 4201 { 4202 if (!m_indexed) 4203 Index (); 4204 4205 m_type_index.Find (type_name, die_offsets); 4206 } 4207 4208 const size_t num_matches = die_offsets.size(); 4209 4210 DWARFCompileUnit* type_cu = NULL; 4211 const DWARFDebugInfoEntry* type_die = NULL; 4212 if (num_matches) 4213 { 4214 DWARFDebugInfo* debug_info = DebugInfo(); 4215 for (size_t i=0; i<num_matches; ++i) 4216 { 4217 const dw_offset_t die_offset = die_offsets[i]; 4218 type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu); 4219 4220 if (type_die) 4221 { 4222 bool try_resolving_type = false; 4223 4224 // Don't try and resolve the DIE we are looking for with the DIE itself! 4225 if (type_die != die) 4226 { 4227 switch (type_die->Tag()) 4228 { 4229 case DW_TAG_class_type: 4230 case DW_TAG_structure_type: 4231 try_resolving_type = true; 4232 break; 4233 default: 4234 break; 4235 } 4236 } 4237 4238 if (try_resolving_type) 4239 { 4240 if (must_be_implementation && type_cu->Supports_DW_AT_APPLE_objc_complete_type()) 4241 try_resolving_type = type_die->GetAttributeValueAsUnsigned (this, type_cu, DW_AT_APPLE_objc_complete_type, 0); 4242 4243 if (try_resolving_type) 4244 { 4245 Type *resolved_type = ResolveType (type_cu, type_die, false); 4246 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) 4247 { 4248 DEBUG_PRINTF ("resolved 0x%8.8llx (cu 0x%8.8llx) from %s to 0x%8.8llx (cu 0x%8.8llx)\n", 4249 MakeUserID(die->GetOffset()), 4250 MakeUserID(curr_cu->GetOffset()), 4251 m_obj_file->GetFileSpec().GetFilename().AsCString(), 4252 MakeUserID(type_die->GetOffset()), 4253 MakeUserID(type_cu->GetOffset())); 4254 4255 if (die) 4256 m_die_to_type[die] = resolved_type; 4257 type_sp = resolved_type->shared_from_this(); 4258 break; 4259 } 4260 } 4261 } 4262 } 4263 else 4264 { 4265 if (m_using_apple_tables) 4266 { 4267 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n", 4268 die_offset, type_name.GetCString()); 4269 } 4270 } 4271 4272 } 4273 } 4274 return type_sp; 4275} 4276 4277//---------------------------------------------------------------------- 4278// This function helps to ensure that the declaration contexts match for 4279// two different DIEs. Often times debug information will refer to a 4280// forward declaration of a type (the equivalent of "struct my_struct;". 4281// There will often be a declaration of that type elsewhere that has the 4282// full definition. When we go looking for the full type "my_struct", we 4283// will find one or more matches in the accelerator tables and we will 4284// then need to make sure the type was in the same declaration context 4285// as the original DIE. This function can efficiently compare two DIEs 4286// and will return true when the declaration context matches, and false 4287// when they don't. 4288//---------------------------------------------------------------------- 4289bool 4290SymbolFileDWARF::DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugInfoEntry *die1, 4291 DWARFCompileUnit* cu2, const DWARFDebugInfoEntry *die2) 4292{ 4293 assert (die1 != die2); 4294 DWARFDIECollection decl_ctx_1; 4295 DWARFDIECollection decl_ctx_2; 4296 //The declaration DIE stack is a stack of the declaration context 4297 // DIEs all the way back to the compile unit. If a type "T" is 4298 // declared inside a class "B", and class "B" is declared inside 4299 // a class "A" and class "A" is in a namespace "lldb", and the 4300 // namespace is in a compile unit, there will be a stack of DIEs: 4301 // 4302 // [0] DW_TAG_class_type for "B" 4303 // [1] DW_TAG_class_type for "A" 4304 // [2] DW_TAG_namespace for "lldb" 4305 // [3] DW_TAG_compile_unit for the source file. 4306 // 4307 // We grab both contexts and make sure that everything matches 4308 // all the way back to the compiler unit. 4309 4310 // First lets grab the decl contexts for both DIEs 4311 die1->GetDeclContextDIEs (this, cu1, decl_ctx_1); 4312 die2->GetDeclContextDIEs (this, cu2, decl_ctx_2); 4313 // Make sure the context arrays have the same size, otherwise 4314 // we are done 4315 const size_t count1 = decl_ctx_1.Size(); 4316 const size_t count2 = decl_ctx_2.Size(); 4317 if (count1 != count2) 4318 return false; 4319 4320 // Make sure the DW_TAG values match all the way back up the the 4321 // compile unit. If they don't, then we are done. 4322 const DWARFDebugInfoEntry *decl_ctx_die1; 4323 const DWARFDebugInfoEntry *decl_ctx_die2; 4324 size_t i; 4325 for (i=0; i<count1; i++) 4326 { 4327 decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i); 4328 decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i); 4329 if (decl_ctx_die1->Tag() != decl_ctx_die2->Tag()) 4330 return false; 4331 } 4332#if defined LLDB_CONFIGURATION_DEBUG 4333 4334 // Make sure the top item in the decl context die array is always 4335 // DW_TAG_compile_unit. If it isn't then something went wrong in 4336 // the DWARFDebugInfoEntry::GetDeclContextDIEs() function... 4337 assert (decl_ctx_1.GetDIEPtrAtIndex (count1 - 1)->Tag() == DW_TAG_compile_unit); 4338 4339#endif 4340 // Always skip the compile unit when comparing by only iterating up to 4341 // "count - 1". Here we compare the names as we go. 4342 for (i=0; i<count1 - 1; i++) 4343 { 4344 decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i); 4345 decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i); 4346 const char *name1 = decl_ctx_die1->GetName(this, cu1); 4347 const char *name2 = decl_ctx_die2->GetName(this, cu2); 4348 // If the string was from a DW_FORM_strp, then the pointer will often 4349 // be the same! 4350 if (name1 == name2) 4351 continue; 4352 4353 // Name pointers are not equal, so only compare the strings 4354 // if both are not NULL. 4355 if (name1 && name2) 4356 { 4357 // If the strings don't compare, we are done... 4358 if (strcmp(name1, name2) != 0) 4359 return false; 4360 } 4361 else 4362 { 4363 // One name was NULL while the other wasn't 4364 return false; 4365 } 4366 } 4367 // We made it through all of the checks and the declaration contexts 4368 // are equal. 4369 return true; 4370} 4371 4372// This function can be used when a DIE is found that is a forward declaration 4373// DIE and we want to try and find a type that has the complete definition. 4374TypeSP 4375SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu, 4376 const DWARFDebugInfoEntry *die, 4377 const ConstString &type_name) 4378{ 4379 TypeSP type_sp; 4380 4381 if (cu == NULL || die == NULL || !type_name) 4382 return type_sp; 4383 4384 DIEArray die_offsets; 4385 4386 if (m_using_apple_tables) 4387 { 4388 if (m_apple_types_ap.get()) 4389 { 4390 if (m_apple_types_ap->GetHeader().header_data.atoms.size() > 1) 4391 { 4392 m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), die->Tag(), die_offsets); 4393 } 4394 else 4395 { 4396 m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets); 4397 } 4398 } 4399 } 4400 else 4401 { 4402 if (!m_indexed) 4403 Index (); 4404 4405 m_type_index.Find (type_name, die_offsets); 4406 } 4407 4408 const size_t num_matches = die_offsets.size(); 4409 4410 const dw_tag_t die_tag = die->Tag(); 4411 4412 DWARFCompileUnit* type_cu = NULL; 4413 const DWARFDebugInfoEntry* type_die = NULL; 4414 if (num_matches) 4415 { 4416 DWARFDebugInfo* debug_info = DebugInfo(); 4417 for (size_t i=0; i<num_matches; ++i) 4418 { 4419 const dw_offset_t die_offset = die_offsets[i]; 4420 type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu); 4421 4422 if (type_die) 4423 { 4424 bool try_resolving_type = false; 4425 4426 // Don't try and resolve the DIE we are looking for with the DIE itself! 4427 if (type_die != die) 4428 { 4429 const dw_tag_t type_die_tag = type_die->Tag(); 4430 // Make sure the tags match 4431 if (type_die_tag == die_tag) 4432 { 4433 // The tags match, lets try resolving this type 4434 try_resolving_type = true; 4435 } 4436 else 4437 { 4438 // The tags don't match, but we need to watch our for a 4439 // forward declaration for a struct and ("struct foo") 4440 // ends up being a class ("class foo { ... };") or 4441 // vice versa. 4442 switch (type_die_tag) 4443 { 4444 case DW_TAG_class_type: 4445 // We had a "class foo", see if we ended up with a "struct foo { ... };" 4446 try_resolving_type = (die_tag == DW_TAG_structure_type); 4447 break; 4448 case DW_TAG_structure_type: 4449 // We had a "struct foo", see if we ended up with a "class foo { ... };" 4450 try_resolving_type = (die_tag == DW_TAG_class_type); 4451 break; 4452 default: 4453 // Tags don't match, don't event try to resolve 4454 // using this type whose name matches.... 4455 break; 4456 } 4457 } 4458 } 4459 4460 if (try_resolving_type) 4461 { 4462 // Make sure the decl contexts match all the way up 4463 if (DIEDeclContextsMatch(cu, die, type_cu, type_die)) 4464 { 4465 Type *resolved_type = ResolveType (type_cu, type_die, false); 4466 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) 4467 { 4468 DEBUG_PRINTF ("resolved 0x%8.8llx (cu 0x%8.8llx) from %s to 0x%8.8llx (cu 0x%8.8llx)\n", 4469 MakeUserID(die->GetOffset()), 4470 MakeUserID(curr_cu->GetOffset()), 4471 m_obj_file->GetFileSpec().GetFilename().AsCString(), 4472 MakeUserID(type_die->GetOffset()), 4473 MakeUserID(type_cu->GetOffset())); 4474 4475 m_die_to_type[die] = resolved_type; 4476 type_sp = resolved_type->shared_from_this(); 4477 break; 4478 } 4479 } 4480 } 4481 } 4482 else 4483 { 4484 if (m_using_apple_tables) 4485 { 4486 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n", 4487 die_offset, type_name.GetCString()); 4488 } 4489 } 4490 4491 } 4492 } 4493 return type_sp; 4494} 4495 4496TypeSP 4497SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr) 4498{ 4499 TypeSP type_sp; 4500 4501 if (type_is_new_ptr) 4502 *type_is_new_ptr = false; 4503 4504#if defined(LLDB_CONFIGURATION_DEBUG) or defined(LLDB_CONFIGURATION_RELEASE) 4505 static DIEStack g_die_stack; 4506 DIEStack::ScopedPopper scoped_die_logger(g_die_stack); 4507#endif 4508 4509 AccessType accessibility = eAccessNone; 4510 if (die != NULL) 4511 { 4512 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); 4513 if (log) 4514 { 4515 const DWARFDebugInfoEntry *context_die; 4516 clang::DeclContext *context = GetClangDeclContextContainingDIE (dwarf_cu, die, &context_die); 4517 4518 GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die 0x%8.8x)) %s name = '%s')", 4519 die->GetOffset(), 4520 context, 4521 context_die->GetOffset(), 4522 DW_TAG_value_to_name(die->Tag()), 4523 die->GetName(this, dwarf_cu)); 4524 4525#if defined(LLDB_CONFIGURATION_DEBUG) or defined(LLDB_CONFIGURATION_RELEASE) 4526 scoped_die_logger.Push (dwarf_cu, die); 4527 g_die_stack.LogDIEs(log.get(), this); 4528#endif 4529 } 4530// 4531// LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); 4532// if (log && dwarf_cu) 4533// { 4534// StreamString s; 4535// die->DumpLocation (this, dwarf_cu, s); 4536// GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData()); 4537// 4538// } 4539 4540 Type *type_ptr = m_die_to_type.lookup (die); 4541 TypeList* type_list = GetTypeList(); 4542 if (type_ptr == NULL) 4543 { 4544 ClangASTContext &ast = GetClangASTContext(); 4545 if (type_is_new_ptr) 4546 *type_is_new_ptr = true; 4547 4548 const dw_tag_t tag = die->Tag(); 4549 4550 bool is_forward_declaration = false; 4551 DWARFDebugInfoEntry::Attributes attributes; 4552 const char *type_name_cstr = NULL; 4553 ConstString type_name_const_str; 4554 Type::ResolveState resolve_state = Type::eResolveStateUnresolved; 4555 size_t byte_size = 0; 4556 bool byte_size_valid = false; 4557 Declaration decl; 4558 4559 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID; 4560 clang_type_t clang_type = NULL; 4561 4562 dw_attr_t attr; 4563 4564 switch (tag) 4565 { 4566 case DW_TAG_base_type: 4567 case DW_TAG_pointer_type: 4568 case DW_TAG_reference_type: 4569 case DW_TAG_typedef: 4570 case DW_TAG_const_type: 4571 case DW_TAG_restrict_type: 4572 case DW_TAG_volatile_type: 4573 case DW_TAG_unspecified_type: 4574 { 4575 // Set a bit that lets us know that we are currently parsing this 4576 m_die_to_type[die] = DIE_IS_BEING_PARSED; 4577 4578 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 4579 uint32_t encoding = 0; 4580 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 4581 4582 if (num_attributes > 0) 4583 { 4584 uint32_t i; 4585 for (i=0; i<num_attributes; ++i) 4586 { 4587 attr = attributes.AttributeAtIndex(i); 4588 DWARFFormValue form_value; 4589 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 4590 { 4591 switch (attr) 4592 { 4593 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 4594 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 4595 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 4596 case DW_AT_name: 4597 4598 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 4599 // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't 4600 // include the "&"... 4601 if (tag == DW_TAG_reference_type) 4602 { 4603 if (strchr (type_name_cstr, '&') == NULL) 4604 type_name_cstr = NULL; 4605 } 4606 if (type_name_cstr) 4607 type_name_const_str.SetCString(type_name_cstr); 4608 break; 4609 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break; 4610 case DW_AT_encoding: encoding = form_value.Unsigned(); break; 4611 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 4612 default: 4613 case DW_AT_sibling: 4614 break; 4615 } 4616 } 4617 } 4618 } 4619 4620 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\") type => 0x%8.8x\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid); 4621 4622 switch (tag) 4623 { 4624 default: 4625 break; 4626 4627 case DW_TAG_unspecified_type: 4628 if (strcmp(type_name_cstr, "nullptr_t") == 0) 4629 { 4630 resolve_state = Type::eResolveStateFull; 4631 clang_type = ast.getASTContext()->NullPtrTy.getAsOpaquePtr(); 4632 break; 4633 } 4634 // Fall through to base type below in case we can handle the type there... 4635 4636 case DW_TAG_base_type: 4637 resolve_state = Type::eResolveStateFull; 4638 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, 4639 encoding, 4640 byte_size * 8); 4641 break; 4642 4643 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break; 4644 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break; 4645 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break; 4646 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break; 4647 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break; 4648 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break; 4649 } 4650 4651 if (clang_type == NULL && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID)) 4652 { 4653 if (type_name_cstr != NULL && sc.comp_unit != NULL && 4654 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus)) 4655 { 4656 static ConstString g_objc_type_name_id("id"); 4657 static ConstString g_objc_type_name_Class("Class"); 4658 static ConstString g_objc_type_name_selector("SEL"); 4659 4660 if (type_name_const_str == g_objc_type_name_id) 4661 { 4662 if (log) 4663 GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.", 4664 die->GetOffset(), 4665 DW_TAG_value_to_name(die->Tag()), 4666 die->GetName(this, dwarf_cu)); 4667 clang_type = ast.GetBuiltInType_objc_id(); 4668 encoding_data_type = Type::eEncodingIsUID; 4669 encoding_uid = LLDB_INVALID_UID; 4670 resolve_state = Type::eResolveStateFull; 4671 4672 } 4673 else if (type_name_const_str == g_objc_type_name_Class) 4674 { 4675 if (log) 4676 GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.", 4677 die->GetOffset(), 4678 DW_TAG_value_to_name(die->Tag()), 4679 die->GetName(this, dwarf_cu)); 4680 clang_type = ast.GetBuiltInType_objc_Class(); 4681 encoding_data_type = Type::eEncodingIsUID; 4682 encoding_uid = LLDB_INVALID_UID; 4683 resolve_state = Type::eResolveStateFull; 4684 } 4685 else if (type_name_const_str == g_objc_type_name_selector) 4686 { 4687 if (log) 4688 GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.", 4689 die->GetOffset(), 4690 DW_TAG_value_to_name(die->Tag()), 4691 die->GetName(this, dwarf_cu)); 4692 clang_type = ast.GetBuiltInType_objc_selector(); 4693 encoding_data_type = Type::eEncodingIsUID; 4694 encoding_uid = LLDB_INVALID_UID; 4695 resolve_state = Type::eResolveStateFull; 4696 } 4697 } 4698 } 4699 4700 type_sp.reset( new Type (MakeUserID(die->GetOffset()), 4701 this, 4702 type_name_const_str, 4703 byte_size, 4704 NULL, 4705 encoding_uid, 4706 encoding_data_type, 4707 &decl, 4708 clang_type, 4709 resolve_state)); 4710 4711 m_die_to_type[die] = type_sp.get(); 4712 4713// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false); 4714// if (encoding_type != NULL) 4715// { 4716// if (encoding_type != DIE_IS_BEING_PARSED) 4717// type_sp->SetEncodingType(encoding_type); 4718// else 4719// m_indirect_fixups.push_back(type_sp.get()); 4720// } 4721 } 4722 break; 4723 4724 case DW_TAG_structure_type: 4725 case DW_TAG_union_type: 4726 case DW_TAG_class_type: 4727 { 4728 // Set a bit that lets us know that we are currently parsing this 4729 m_die_to_type[die] = DIE_IS_BEING_PARSED; 4730 4731 LanguageType class_language = eLanguageTypeUnknown; 4732 bool is_complete_objc_class = false; 4733 //bool struct_is_class = false; 4734 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 4735 if (num_attributes > 0) 4736 { 4737 uint32_t i; 4738 for (i=0; i<num_attributes; ++i) 4739 { 4740 attr = attributes.AttributeAtIndex(i); 4741 DWARFFormValue form_value; 4742 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 4743 { 4744 switch (attr) 4745 { 4746 case DW_AT_decl_file: 4747 if (dwarf_cu->DW_AT_decl_file_attributes_are_invalid()) 4748 { 4749 // llvm-gcc outputs invalid DW_AT_decl_file attributes that always 4750 // point to the compile unit file, so we clear this invalid value 4751 // so that we can still unique types efficiently. 4752 decl.SetFile(FileSpec ("<invalid>", false)); 4753 } 4754 else 4755 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); 4756 break; 4757 4758 case DW_AT_decl_line: 4759 decl.SetLine(form_value.Unsigned()); 4760 break; 4761 4762 case DW_AT_decl_column: 4763 decl.SetColumn(form_value.Unsigned()); 4764 break; 4765 4766 case DW_AT_name: 4767 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 4768 type_name_const_str.SetCString(type_name_cstr); 4769 break; 4770 4771 case DW_AT_byte_size: 4772 byte_size = form_value.Unsigned(); 4773 byte_size_valid = true; 4774 break; 4775 4776 case DW_AT_accessibility: 4777 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); 4778 break; 4779 4780 case DW_AT_declaration: 4781 is_forward_declaration = form_value.Unsigned() != 0; 4782 break; 4783 4784 case DW_AT_APPLE_runtime_class: 4785 class_language = (LanguageType)form_value.Signed(); 4786 break; 4787 4788 case DW_AT_APPLE_objc_complete_type: 4789 is_complete_objc_class = form_value.Signed(); 4790 break; 4791 4792 case DW_AT_allocated: 4793 case DW_AT_associated: 4794 case DW_AT_data_location: 4795 case DW_AT_description: 4796 case DW_AT_start_scope: 4797 case DW_AT_visibility: 4798 default: 4799 case DW_AT_sibling: 4800 break; 4801 } 4802 } 4803 } 4804 } 4805 4806 UniqueDWARFASTType unique_ast_entry; 4807 4808 // Only try and unique the type if it has a name. 4809 if (type_name_const_str && 4810 GetUniqueDWARFASTTypeMap().Find (type_name_const_str, 4811 this, 4812 dwarf_cu, 4813 die, 4814 decl, 4815 byte_size_valid ? byte_size : -1, 4816 unique_ast_entry)) 4817 { 4818 // We have already parsed this type or from another 4819 // compile unit. GCC loves to use the "one definition 4820 // rule" which can result in multiple definitions 4821 // of the same class over and over in each compile 4822 // unit. 4823 type_sp = unique_ast_entry.m_type_sp; 4824 if (type_sp) 4825 { 4826 m_die_to_type[die] = type_sp.get(); 4827 return type_sp; 4828 } 4829 } 4830 4831 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr); 4832 4833 int tag_decl_kind = -1; 4834 AccessType default_accessibility = eAccessNone; 4835 if (tag == DW_TAG_structure_type) 4836 { 4837 tag_decl_kind = clang::TTK_Struct; 4838 default_accessibility = eAccessPublic; 4839 } 4840 else if (tag == DW_TAG_union_type) 4841 { 4842 tag_decl_kind = clang::TTK_Union; 4843 default_accessibility = eAccessPublic; 4844 } 4845 else if (tag == DW_TAG_class_type) 4846 { 4847 tag_decl_kind = clang::TTK_Class; 4848 default_accessibility = eAccessPrivate; 4849 } 4850 4851 if (byte_size_valid && byte_size == 0 && type_name_cstr && 4852 die->HasChildren() == false && 4853 sc.comp_unit->GetLanguage() == eLanguageTypeObjC) 4854 { 4855 // Work around an issue with clang at the moment where 4856 // forward declarations for objective C classes are emitted 4857 // as: 4858 // DW_TAG_structure_type [2] 4859 // DW_AT_name( "ForwardObjcClass" ) 4860 // DW_AT_byte_size( 0x00 ) 4861 // DW_AT_decl_file( "..." ) 4862 // DW_AT_decl_line( 1 ) 4863 // 4864 // Note that there is no DW_AT_declaration and there are 4865 // no children, and the byte size is zero. 4866 is_forward_declaration = true; 4867 } 4868 4869 if (class_language == eLanguageTypeObjC) 4870 { 4871 if (!is_complete_objc_class && Supports_DW_AT_APPLE_objc_complete_type(dwarf_cu)) 4872 { 4873 // We have a valid eSymbolTypeObjCClass class symbol whose 4874 // name matches the current objective C class that we 4875 // are trying to find and this DIE isn't the complete 4876 // definition (we checked is_complete_objc_class above and 4877 // know it is false), so the real definition is in here somewhere 4878 type_sp = FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true); 4879 4880 if (!type_sp && m_debug_map_symfile) 4881 { 4882 // We weren't able to find a full declaration in 4883 // this DWARF, see if we have a declaration anywhere 4884 // else... 4885 type_sp = m_debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true); 4886 } 4887 4888 if (type_sp) 4889 { 4890 if (log) 4891 { 4892 GetObjectFile()->GetModule()->LogMessage (log.get(), 4893 "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an incomplete objc type, complete type is 0x%8.8llx", 4894 this, 4895 die->GetOffset(), 4896 DW_TAG_value_to_name(tag), 4897 type_name_cstr, 4898 type_sp->GetID()); 4899 } 4900 4901 // We found a real definition for this type elsewhere 4902 // so lets use it and cache the fact that we found 4903 // a complete type for this die 4904 m_die_to_type[die] = type_sp.get(); 4905 return type_sp; 4906 } 4907 } 4908 } 4909 4910 4911 if (is_forward_declaration) 4912 { 4913 // We have a forward declaration to a type and we need 4914 // to try and find a full declaration. We look in the 4915 // current type index just in case we have a forward 4916 // declaration followed by an actual declarations in the 4917 // DWARF. If this fails, we need to look elsewhere... 4918 if (log) 4919 { 4920 GetObjectFile()->GetModule()->LogMessage (log.get(), 4921 "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, trying to find complete type", 4922 this, 4923 die->GetOffset(), 4924 DW_TAG_value_to_name(tag), 4925 type_name_cstr); 4926 } 4927 4928 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); 4929 4930 if (!type_sp && m_debug_map_symfile) 4931 { 4932 // We weren't able to find a full declaration in 4933 // this DWARF, see if we have a declaration anywhere 4934 // else... 4935 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); 4936 } 4937 4938 if (type_sp) 4939 { 4940 if (log) 4941 { 4942 GetObjectFile()->GetModule()->LogMessage (log.get(), 4943 "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8llx", 4944 this, 4945 die->GetOffset(), 4946 DW_TAG_value_to_name(tag), 4947 type_name_cstr, 4948 type_sp->GetID()); 4949 } 4950 4951 // We found a real definition for this type elsewhere 4952 // so lets use it and cache the fact that we found 4953 // a complete type for this die 4954 m_die_to_type[die] = type_sp.get(); 4955 return type_sp; 4956 } 4957 } 4958 assert (tag_decl_kind != -1); 4959 bool clang_type_was_created = false; 4960 clang_type = m_forward_decl_die_to_clang_type.lookup (die); 4961 if (clang_type == NULL) 4962 { 4963 const DWARFDebugInfoEntry *decl_ctx_die; 4964 4965 clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die); 4966 if (accessibility == eAccessNone && decl_ctx) 4967 { 4968 // Check the decl context that contains this class/struct/union. 4969 // If it is a class we must give it an accessability. 4970 const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind(); 4971 if (DeclKindIsCXXClass (containing_decl_kind)) 4972 accessibility = default_accessibility; 4973 } 4974 4975 if (type_name_cstr && strchr (type_name_cstr, '<')) 4976 { 4977 ClangASTContext::TemplateParameterInfos template_param_infos; 4978 if (ParseTemplateParameterInfos (dwarf_cu, die, template_param_infos)) 4979 { 4980 clang::ClassTemplateDecl *class_template_decl = ParseClassTemplateDecl (decl_ctx, 4981 accessibility, 4982 type_name_cstr, 4983 tag_decl_kind, 4984 template_param_infos); 4985 4986 clang::ClassTemplateSpecializationDecl *class_specialization_decl = ast.CreateClassTemplateSpecializationDecl (decl_ctx, 4987 class_template_decl, 4988 tag_decl_kind, 4989 template_param_infos); 4990 clang_type = ast.CreateClassTemplateSpecializationType (class_specialization_decl); 4991 clang_type_was_created = true; 4992 } 4993 } 4994 4995 if (!clang_type_was_created) 4996 { 4997 clang_type_was_created = true; 4998 clang_type = ast.CreateRecordType (decl_ctx, 4999 accessibility, 5000 type_name_cstr, 5001 tag_decl_kind, 5002 class_language); 5003 } 5004 } 5005 5006 // Store a forward declaration to this class type in case any 5007 // parameters in any class methods need it for the clang 5008 // types for function prototypes. 5009 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); 5010 type_sp.reset (new Type (MakeUserID(die->GetOffset()), 5011 this, 5012 type_name_const_str, 5013 byte_size, 5014 NULL, 5015 LLDB_INVALID_UID, 5016 Type::eEncodingIsUID, 5017 &decl, 5018 clang_type, 5019 Type::eResolveStateForward)); 5020 5021 type_sp->SetIsCompleteObjCClass(is_complete_objc_class); 5022 5023 5024 // Add our type to the unique type map so we don't 5025 // end up creating many copies of the same type over 5026 // and over in the ASTContext for our module 5027 unique_ast_entry.m_type_sp = type_sp; 5028 unique_ast_entry.m_symfile = this; 5029 unique_ast_entry.m_cu = dwarf_cu; 5030 unique_ast_entry.m_die = die; 5031 unique_ast_entry.m_declaration = decl; 5032 unique_ast_entry.m_byte_size = byte_size; 5033 GetUniqueDWARFASTTypeMap().Insert (type_name_const_str, 5034 unique_ast_entry); 5035 5036 if (!is_forward_declaration) 5037 { 5038 if (die->HasChildren() == false) 5039 { 5040 // No children for this struct/union/class, lets finish it 5041 ast.StartTagDeclarationDefinition (clang_type); 5042 ast.CompleteTagDeclarationDefinition (clang_type); 5043 } 5044 else if (clang_type_was_created) 5045 { 5046 // Leave this as a forward declaration until we need 5047 // to know the details of the type. lldb_private::Type 5048 // will automatically call the SymbolFile virtual function 5049 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)" 5050 // When the definition needs to be defined. 5051 m_forward_decl_die_to_clang_type[die] = clang_type; 5052 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die; 5053 ClangASTContext::SetHasExternalStorage (clang_type, true); 5054 } 5055 } 5056 5057 } 5058 break; 5059 5060 case DW_TAG_enumeration_type: 5061 { 5062 // Set a bit that lets us know that we are currently parsing this 5063 m_die_to_type[die] = DIE_IS_BEING_PARSED; 5064 5065 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET; 5066 5067 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 5068 if (num_attributes > 0) 5069 { 5070 uint32_t i; 5071 5072 for (i=0; i<num_attributes; ++i) 5073 { 5074 attr = attributes.AttributeAtIndex(i); 5075 DWARFFormValue form_value; 5076 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 5077 { 5078 switch (attr) 5079 { 5080 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 5081 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 5082 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 5083 case DW_AT_name: 5084 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 5085 type_name_const_str.SetCString(type_name_cstr); 5086 break; 5087 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 5088 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break; 5089 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 5090 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 5091 case DW_AT_allocated: 5092 case DW_AT_associated: 5093 case DW_AT_bit_stride: 5094 case DW_AT_byte_stride: 5095 case DW_AT_data_location: 5096 case DW_AT_description: 5097 case DW_AT_start_scope: 5098 case DW_AT_visibility: 5099 case DW_AT_specification: 5100 case DW_AT_abstract_origin: 5101 case DW_AT_sibling: 5102 break; 5103 } 5104 } 5105 } 5106 5107 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr); 5108 5109 clang_type_t enumerator_clang_type = NULL; 5110 clang_type = m_forward_decl_die_to_clang_type.lookup (die); 5111 if (clang_type == NULL) 5112 { 5113 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, 5114 DW_ATE_signed, 5115 byte_size * 8); 5116 clang_type = ast.CreateEnumerationType (type_name_cstr, 5117 GetClangDeclContextContainingDIE (dwarf_cu, die, NULL), 5118 decl, 5119 enumerator_clang_type); 5120 } 5121 else 5122 { 5123 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type); 5124 assert (enumerator_clang_type != NULL); 5125 } 5126 5127 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); 5128 5129 type_sp.reset( new Type (MakeUserID(die->GetOffset()), 5130 this, 5131 type_name_const_str, 5132 byte_size, 5133 NULL, 5134 encoding_uid, 5135 Type::eEncodingIsUID, 5136 &decl, 5137 clang_type, 5138 Type::eResolveStateForward)); 5139 5140 ast.StartTagDeclarationDefinition (clang_type); 5141 if (die->HasChildren()) 5142 { 5143 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu)); 5144 ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die); 5145 } 5146 ast.CompleteTagDeclarationDefinition (clang_type); 5147 } 5148 } 5149 break; 5150 5151 case DW_TAG_inlined_subroutine: 5152 case DW_TAG_subprogram: 5153 case DW_TAG_subroutine_type: 5154 { 5155 // Set a bit that lets us know that we are currently parsing this 5156 m_die_to_type[die] = DIE_IS_BEING_PARSED; 5157 5158 const char *mangled = NULL; 5159 dw_offset_t type_die_offset = DW_INVALID_OFFSET; 5160 bool is_variadic = false; 5161 bool is_inline = false; 5162 bool is_static = false; 5163 bool is_virtual = false; 5164 bool is_explicit = false; 5165 bool is_artificial = false; 5166 dw_offset_t specification_die_offset = DW_INVALID_OFFSET; 5167 dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET; 5168 5169 unsigned type_quals = 0; 5170 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern 5171 5172 5173 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 5174 if (num_attributes > 0) 5175 { 5176 uint32_t i; 5177 for (i=0; i<num_attributes; ++i) 5178 { 5179 attr = attributes.AttributeAtIndex(i); 5180 DWARFFormValue form_value; 5181 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 5182 { 5183 switch (attr) 5184 { 5185 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 5186 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 5187 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 5188 case DW_AT_name: 5189 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 5190 type_name_const_str.SetCString(type_name_cstr); 5191 break; 5192 5193 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break; 5194 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; 5195 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 5196 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 5197 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break; 5198 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break; 5199 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break; 5200 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break; 5201 5202 5203 case DW_AT_external: 5204 if (form_value.Unsigned()) 5205 { 5206 if (storage == clang::SC_None) 5207 storage = clang::SC_Extern; 5208 else 5209 storage = clang::SC_PrivateExtern; 5210 } 5211 break; 5212 5213 case DW_AT_specification: 5214 specification_die_offset = form_value.Reference(dwarf_cu); 5215 break; 5216 5217 case DW_AT_abstract_origin: 5218 abstract_origin_die_offset = form_value.Reference(dwarf_cu); 5219 break; 5220 5221 case DW_AT_allocated: 5222 case DW_AT_associated: 5223 case DW_AT_address_class: 5224 case DW_AT_calling_convention: 5225 case DW_AT_data_location: 5226 case DW_AT_elemental: 5227 case DW_AT_entry_pc: 5228 case DW_AT_frame_base: 5229 case DW_AT_high_pc: 5230 case DW_AT_low_pc: 5231 case DW_AT_object_pointer: 5232 case DW_AT_prototyped: 5233 case DW_AT_pure: 5234 case DW_AT_ranges: 5235 case DW_AT_recursive: 5236 case DW_AT_return_addr: 5237 case DW_AT_segment: 5238 case DW_AT_start_scope: 5239 case DW_AT_static_link: 5240 case DW_AT_trampoline: 5241 case DW_AT_visibility: 5242 case DW_AT_vtable_elem_location: 5243 case DW_AT_description: 5244 case DW_AT_sibling: 5245 break; 5246 } 5247 } 5248 } 5249 } 5250 5251 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr); 5252 5253 clang_type_t return_clang_type = NULL; 5254 Type *func_type = NULL; 5255 5256 if (type_die_offset != DW_INVALID_OFFSET) 5257 func_type = ResolveTypeUID(type_die_offset); 5258 5259 if (func_type) 5260 return_clang_type = func_type->GetClangForwardType(); 5261 else 5262 return_clang_type = ast.GetBuiltInType_void(); 5263 5264 5265 std::vector<clang_type_t> function_param_types; 5266 std::vector<clang::ParmVarDecl*> function_param_decls; 5267 5268 // Parse the function children for the parameters 5269 5270 const DWARFDebugInfoEntry *decl_ctx_die = NULL; 5271 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die); 5272 const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind(); 5273 5274 const bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind); 5275 // Start off static. This will be set to false in ParseChildParameters(...) 5276 // if we find a "this" paramters as the first parameter 5277 if (is_cxx_method) 5278 is_static = true; 5279 ClangASTContext::TemplateParameterInfos template_param_infos; 5280 5281 if (die->HasChildren()) 5282 { 5283 bool skip_artificial = true; 5284 ParseChildParameters (sc, 5285 containing_decl_ctx, 5286 dwarf_cu, 5287 die, 5288 skip_artificial, 5289 is_static, 5290 type_list, 5291 function_param_types, 5292 function_param_decls, 5293 type_quals, 5294 template_param_infos); 5295 } 5296 5297 // clang_type will get the function prototype clang type after this call 5298 clang_type = ast.CreateFunctionType (return_clang_type, 5299 &function_param_types[0], 5300 function_param_types.size(), 5301 is_variadic, 5302 type_quals); 5303 5304 if (type_name_cstr) 5305 { 5306 bool type_handled = false; 5307 if (tag == DW_TAG_subprogram) 5308 { 5309 ConstString class_name; 5310 ConstString class_name_no_category; 5311 if (ObjCLanguageRuntime::ParseMethodName (type_name_cstr, &class_name, NULL, NULL, &class_name_no_category)) 5312 { 5313 // Use the class name with no category if there is one 5314 if (class_name_no_category) 5315 class_name = class_name_no_category; 5316 5317 SymbolContext empty_sc; 5318 clang_type_t class_opaque_type = NULL; 5319 if (class_name) 5320 { 5321 TypeList types; 5322 TypeSP complete_objc_class_type_sp (FindCompleteObjCDefinitionTypeForDIE (NULL, class_name, false)); 5323 5324 if (complete_objc_class_type_sp) 5325 { 5326 clang_type_t type_clang_forward_type = complete_objc_class_type_sp->GetClangForwardType(); 5327 if (ClangASTContext::IsObjCClassType (type_clang_forward_type)) 5328 class_opaque_type = type_clang_forward_type; 5329 } 5330 } 5331 5332 if (class_opaque_type) 5333 { 5334 // If accessibility isn't set to anything valid, assume public for 5335 // now... 5336 if (accessibility == eAccessNone) 5337 accessibility = eAccessPublic; 5338 5339 clang::ObjCMethodDecl *objc_method_decl; 5340 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type, 5341 type_name_cstr, 5342 clang_type, 5343 accessibility); 5344 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die); 5345 type_handled = objc_method_decl != NULL; 5346 } 5347 } 5348 else if (is_cxx_method) 5349 { 5350 // Look at the parent of this DIE and see if is is 5351 // a class or struct and see if this is actually a 5352 // C++ method 5353 Type *class_type = ResolveType (dwarf_cu, decl_ctx_die); 5354 if (class_type) 5355 { 5356 if (specification_die_offset != DW_INVALID_OFFSET) 5357 { 5358 // We have a specification which we are going to base our function 5359 // prototype off of, so we need this type to be completed so that the 5360 // m_die_to_decl_ctx for the method in the specification has a valid 5361 // clang decl context. 5362 class_type->GetClangForwardType(); 5363 // If we have a specification, then the function type should have been 5364 // made with the specification and not with this die. 5365 DWARFCompileUnitSP spec_cu_sp; 5366 const DWARFDebugInfoEntry* spec_die = DebugInfo()->GetDIEPtr(specification_die_offset, &spec_cu_sp); 5367 clang::DeclContext *spec_clang_decl_ctx = GetClangDeclContextForDIE (sc, dwarf_cu, spec_die); 5368 if (spec_clang_decl_ctx) 5369 { 5370 LinkDeclContextToDIE(spec_clang_decl_ctx, die); 5371 } 5372 else 5373 { 5374 GetObjectFile()->GetModule()->ReportWarning ("0x%8.8llx: DW_AT_specification(0x%8.8x) has no decl\n", 5375 MakeUserID(die->GetOffset()), 5376 specification_die_offset); 5377 } 5378 type_handled = true; 5379 } 5380 else if (abstract_origin_die_offset != DW_INVALID_OFFSET) 5381 { 5382 // We have a specification which we are going to base our function 5383 // prototype off of, so we need this type to be completed so that the 5384 // m_die_to_decl_ctx for the method in the abstract origin has a valid 5385 // clang decl context. 5386 class_type->GetClangForwardType(); 5387 5388 DWARFCompileUnitSP abs_cu_sp; 5389 const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp); 5390 clang::DeclContext *abs_clang_decl_ctx = GetClangDeclContextForDIE (sc, dwarf_cu, abs_die); 5391 if (abs_clang_decl_ctx) 5392 { 5393 LinkDeclContextToDIE (abs_clang_decl_ctx, die); 5394 } 5395 else 5396 { 5397 GetObjectFile()->GetModule()->ReportWarning ("0x%8.8llx: DW_AT_abstract_origin(0x%8.8x) has no decl\n", 5398 MakeUserID(die->GetOffset()), 5399 abstract_origin_die_offset); 5400 } 5401 type_handled = true; 5402 } 5403 else 5404 { 5405 clang_type_t class_opaque_type = class_type->GetClangForwardType(); 5406 if (ClangASTContext::IsCXXClassType (class_opaque_type)) 5407 { 5408 if (ClangASTContext::IsBeingDefined (class_opaque_type)) 5409 { 5410 // Neither GCC 4.2 nor clang++ currently set a valid accessibility 5411 // in the DWARF for C++ methods... Default to public for now... 5412 if (accessibility == eAccessNone) 5413 accessibility = eAccessPublic; 5414 5415 if (!is_static && !die->HasChildren()) 5416 { 5417 // We have a C++ member function with no children (this pointer!) 5418 // and clang will get mad if we try and make a function that isn't 5419 // well formed in the DWARF, so we will just skip it... 5420 type_handled = true; 5421 } 5422 else 5423 { 5424 clang::CXXMethodDecl *cxx_method_decl; 5425 // REMOVE THE CRASH DESCRIPTION BELOW 5426 Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8llx from %s/%s", 5427 type_name_cstr, 5428 class_type->GetName().GetCString(), 5429 MakeUserID(die->GetOffset()), 5430 m_obj_file->GetFileSpec().GetDirectory().GetCString(), 5431 m_obj_file->GetFileSpec().GetFilename().GetCString()); 5432 5433 const bool is_attr_used = false; 5434 5435 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type, 5436 type_name_cstr, 5437 clang_type, 5438 accessibility, 5439 is_virtual, 5440 is_static, 5441 is_inline, 5442 is_explicit, 5443 is_attr_used, 5444 is_artificial); 5445 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die); 5446 5447 Host::SetCrashDescription (NULL); 5448 5449 type_handled = cxx_method_decl != NULL; 5450 } 5451 } 5452 else 5453 { 5454 // We were asked to parse the type for a method in a class, yet the 5455 // class hasn't been asked to complete itself through the 5456 // clang::ExternalASTSource protocol, so we need to just have the 5457 // class complete itself and do things the right way, then our 5458 // DIE should then have an entry in the m_die_to_type map. First 5459 // we need to modify the m_die_to_type so it doesn't think we are 5460 // trying to parse this DIE anymore... 5461 m_die_to_type[die] = NULL; 5462 5463 // Now we get the full type to force our class type to complete itself 5464 // using the clang::ExternalASTSource protocol which will parse all 5465 // base classes and all methods (including the method for this DIE). 5466 class_type->GetClangFullType(); 5467 5468 // The type for this DIE should have been filled in the function call above 5469 type_ptr = m_die_to_type[die]; 5470 if (type_ptr) 5471 { 5472 type_sp = type_ptr->shared_from_this(); 5473 break; 5474 } 5475 } 5476 } 5477 } 5478 } 5479 } 5480 } 5481 5482 if (!type_handled) 5483 { 5484 // We just have a function that isn't part of a class 5485 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (containing_decl_ctx, 5486 type_name_cstr, 5487 clang_type, 5488 storage, 5489 is_inline); 5490 5491// if (template_param_infos.GetSize() > 0) 5492// { 5493// clang::FunctionTemplateDecl *func_template_decl = ast.CreateFunctionTemplateDecl (containing_decl_ctx, 5494// function_decl, 5495// type_name_cstr, 5496// template_param_infos); 5497// 5498// ast.CreateFunctionTemplateSpecializationInfo (function_decl, 5499// func_template_decl, 5500// template_param_infos); 5501// } 5502 // Add the decl to our DIE to decl context map 5503 assert (function_decl); 5504 LinkDeclContextToDIE(function_decl, die); 5505 if (!function_param_decls.empty()) 5506 ast.SetFunctionParameters (function_decl, 5507 &function_param_decls.front(), 5508 function_param_decls.size()); 5509 } 5510 } 5511 type_sp.reset( new Type (MakeUserID(die->GetOffset()), 5512 this, 5513 type_name_const_str, 5514 0, 5515 NULL, 5516 LLDB_INVALID_UID, 5517 Type::eEncodingIsUID, 5518 &decl, 5519 clang_type, 5520 Type::eResolveStateFull)); 5521 assert(type_sp.get()); 5522 } 5523 break; 5524 5525 case DW_TAG_array_type: 5526 { 5527 // Set a bit that lets us know that we are currently parsing this 5528 m_die_to_type[die] = DIE_IS_BEING_PARSED; 5529 5530 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET; 5531 int64_t first_index = 0; 5532 uint32_t byte_stride = 0; 5533 uint32_t bit_stride = 0; 5534 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 5535 5536 if (num_attributes > 0) 5537 { 5538 uint32_t i; 5539 for (i=0; i<num_attributes; ++i) 5540 { 5541 attr = attributes.AttributeAtIndex(i); 5542 DWARFFormValue form_value; 5543 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 5544 { 5545 switch (attr) 5546 { 5547 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 5548 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 5549 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 5550 case DW_AT_name: 5551 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 5552 type_name_const_str.SetCString(type_name_cstr); 5553 break; 5554 5555 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; 5556 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break; 5557 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break; 5558 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break; 5559 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 5560 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 5561 case DW_AT_allocated: 5562 case DW_AT_associated: 5563 case DW_AT_data_location: 5564 case DW_AT_description: 5565 case DW_AT_ordering: 5566 case DW_AT_start_scope: 5567 case DW_AT_visibility: 5568 case DW_AT_specification: 5569 case DW_AT_abstract_origin: 5570 case DW_AT_sibling: 5571 break; 5572 } 5573 } 5574 } 5575 5576 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr); 5577 5578 Type *element_type = ResolveTypeUID(type_die_offset); 5579 5580 if (element_type) 5581 { 5582 std::vector<uint64_t> element_orders; 5583 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride); 5584 // We have an array that claims to have no members, lets give it at least one member... 5585 if (element_orders.empty()) 5586 element_orders.push_back (1); 5587 if (byte_stride == 0 && bit_stride == 0) 5588 byte_stride = element_type->GetByteSize(); 5589 clang_type_t array_element_type = element_type->GetClangForwardType(); 5590 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; 5591 uint64_t num_elements = 0; 5592 std::vector<uint64_t>::const_reverse_iterator pos; 5593 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend(); 5594 for (pos = element_orders.rbegin(); pos != end; ++pos) 5595 { 5596 num_elements = *pos; 5597 clang_type = ast.CreateArrayType (array_element_type, 5598 num_elements, 5599 num_elements * array_element_bit_stride); 5600 array_element_type = clang_type; 5601 array_element_bit_stride = array_element_bit_stride * num_elements; 5602 } 5603 ConstString empty_name; 5604 type_sp.reset( new Type (MakeUserID(die->GetOffset()), 5605 this, 5606 empty_name, 5607 array_element_bit_stride / 8, 5608 NULL, 5609 type_die_offset, 5610 Type::eEncodingIsUID, 5611 &decl, 5612 clang_type, 5613 Type::eResolveStateFull)); 5614 type_sp->SetEncodingType (element_type); 5615 } 5616 } 5617 } 5618 break; 5619 5620 case DW_TAG_ptr_to_member_type: 5621 { 5622 dw_offset_t type_die_offset = DW_INVALID_OFFSET; 5623 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET; 5624 5625 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 5626 5627 if (num_attributes > 0) { 5628 uint32_t i; 5629 for (i=0; i<num_attributes; ++i) 5630 { 5631 attr = attributes.AttributeAtIndex(i); 5632 DWARFFormValue form_value; 5633 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 5634 { 5635 switch (attr) 5636 { 5637 case DW_AT_type: 5638 type_die_offset = form_value.Reference(dwarf_cu); break; 5639 case DW_AT_containing_type: 5640 containing_type_die_offset = form_value.Reference(dwarf_cu); break; 5641 } 5642 } 5643 } 5644 5645 Type *pointee_type = ResolveTypeUID(type_die_offset); 5646 Type *class_type = ResolveTypeUID(containing_type_die_offset); 5647 5648 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType(); 5649 clang_type_t class_clang_type = class_type->GetClangLayoutType(); 5650 5651 clang_type = ast.CreateMemberPointerType(pointee_clang_type, 5652 class_clang_type); 5653 5654 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(), 5655 clang_type) / 8; 5656 5657 type_sp.reset( new Type (MakeUserID(die->GetOffset()), 5658 this, 5659 type_name_const_str, 5660 byte_size, 5661 NULL, 5662 LLDB_INVALID_UID, 5663 Type::eEncodingIsUID, 5664 NULL, 5665 clang_type, 5666 Type::eResolveStateForward)); 5667 } 5668 5669 break; 5670 } 5671 default: 5672 assert(false && "Unhandled type tag!"); 5673 break; 5674 } 5675 5676 if (type_sp.get()) 5677 { 5678 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die); 5679 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 5680 5681 SymbolContextScope * symbol_context_scope = NULL; 5682 if (sc_parent_tag == DW_TAG_compile_unit) 5683 { 5684 symbol_context_scope = sc.comp_unit; 5685 } 5686 else if (sc.function != NULL) 5687 { 5688 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset())); 5689 if (symbol_context_scope == NULL) 5690 symbol_context_scope = sc.function; 5691 } 5692 5693 if (symbol_context_scope != NULL) 5694 { 5695 type_sp->SetSymbolContextScope(symbol_context_scope); 5696 } 5697 5698 // We are ready to put this type into the uniqued list up at the module level 5699 type_list->Insert (type_sp); 5700 5701 m_die_to_type[die] = type_sp.get(); 5702 } 5703 } 5704 else if (type_ptr != DIE_IS_BEING_PARSED) 5705 { 5706 type_sp = type_ptr->shared_from_this(); 5707 } 5708 } 5709 return type_sp; 5710} 5711 5712size_t 5713SymbolFileDWARF::ParseTypes 5714( 5715 const SymbolContext& sc, 5716 DWARFCompileUnit* dwarf_cu, 5717 const DWARFDebugInfoEntry *die, 5718 bool parse_siblings, 5719 bool parse_children 5720) 5721{ 5722 size_t types_added = 0; 5723 while (die != NULL) 5724 { 5725 bool type_is_new = false; 5726 if (ParseType(sc, dwarf_cu, die, &type_is_new).get()) 5727 { 5728 if (type_is_new) 5729 ++types_added; 5730 } 5731 5732 if (parse_children && die->HasChildren()) 5733 { 5734 if (die->Tag() == DW_TAG_subprogram) 5735 { 5736 SymbolContext child_sc(sc); 5737 child_sc.function = sc.comp_unit->FindFunctionByUID(MakeUserID(die->GetOffset())).get(); 5738 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true); 5739 } 5740 else 5741 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true); 5742 } 5743 5744 if (parse_siblings) 5745 die = die->GetSibling(); 5746 else 5747 die = NULL; 5748 } 5749 return types_added; 5750} 5751 5752 5753size_t 5754SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc) 5755{ 5756 assert(sc.comp_unit && sc.function); 5757 size_t functions_added = 0; 5758 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 5759 if (dwarf_cu) 5760 { 5761 dw_offset_t function_die_offset = sc.function->GetID(); 5762 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset); 5763 if (function_die) 5764 { 5765 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, 0); 5766 } 5767 } 5768 5769 return functions_added; 5770} 5771 5772 5773size_t 5774SymbolFileDWARF::ParseTypes (const SymbolContext &sc) 5775{ 5776 // At least a compile unit must be valid 5777 assert(sc.comp_unit); 5778 size_t types_added = 0; 5779 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 5780 if (dwarf_cu) 5781 { 5782 if (sc.function) 5783 { 5784 dw_offset_t function_die_offset = sc.function->GetID(); 5785 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset); 5786 if (func_die && func_die->HasChildren()) 5787 { 5788 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true); 5789 } 5790 } 5791 else 5792 { 5793 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE(); 5794 if (dwarf_cu_die && dwarf_cu_die->HasChildren()) 5795 { 5796 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true); 5797 } 5798 } 5799 } 5800 5801 return types_added; 5802} 5803 5804size_t 5805SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc) 5806{ 5807 if (sc.comp_unit != NULL) 5808 { 5809 DWARFDebugInfo* info = DebugInfo(); 5810 if (info == NULL) 5811 return 0; 5812 5813 uint32_t cu_idx = UINT32_MAX; 5814 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get(); 5815 5816 if (dwarf_cu == NULL) 5817 return 0; 5818 5819 if (sc.function) 5820 { 5821 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID()); 5822 5823 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS); 5824 if (func_lo_pc != DW_INVALID_ADDRESS) 5825 { 5826 const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true); 5827 5828 // Let all blocks know they have parse all their variables 5829 sc.function->GetBlock (false).SetDidParseVariables (true, true); 5830 return num_variables; 5831 } 5832 } 5833 else if (sc.comp_unit) 5834 { 5835 uint32_t vars_added = 0; 5836 VariableListSP variables (sc.comp_unit->GetVariableList(false)); 5837 5838 if (variables.get() == NULL) 5839 { 5840 variables.reset(new VariableList()); 5841 sc.comp_unit->SetVariableList(variables); 5842 5843 DWARFCompileUnit* match_dwarf_cu = NULL; 5844 const DWARFDebugInfoEntry* die = NULL; 5845 DIEArray die_offsets; 5846 if (m_using_apple_tables) 5847 { 5848 if (m_apple_names_ap.get()) 5849 { 5850 DWARFMappedHash::DIEInfoArray hash_data_array; 5851 if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(), 5852 dwarf_cu->GetNextCompileUnitOffset(), 5853 hash_data_array)) 5854 { 5855 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets); 5856 } 5857 } 5858 } 5859 else 5860 { 5861 // Index if we already haven't to make sure the compile units 5862 // get indexed and make their global DIE index list 5863 if (!m_indexed) 5864 Index (); 5865 5866 m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(), 5867 dwarf_cu->GetNextCompileUnitOffset(), 5868 die_offsets); 5869 } 5870 5871 const size_t num_matches = die_offsets.size(); 5872 if (num_matches) 5873 { 5874 DWARFDebugInfo* debug_info = DebugInfo(); 5875 for (size_t i=0; i<num_matches; ++i) 5876 { 5877 const dw_offset_t die_offset = die_offsets[i]; 5878 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &match_dwarf_cu); 5879 if (die) 5880 { 5881 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS)); 5882 if (var_sp) 5883 { 5884 variables->AddVariableIfUnique (var_sp); 5885 ++vars_added; 5886 } 5887 } 5888 else 5889 { 5890 if (m_using_apple_tables) 5891 { 5892 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x)\n", die_offset); 5893 } 5894 } 5895 5896 } 5897 } 5898 } 5899 return vars_added; 5900 } 5901 } 5902 return 0; 5903} 5904 5905 5906VariableSP 5907SymbolFileDWARF::ParseVariableDIE 5908( 5909 const SymbolContext& sc, 5910 DWARFCompileUnit* dwarf_cu, 5911 const DWARFDebugInfoEntry *die, 5912 const lldb::addr_t func_low_pc 5913) 5914{ 5915 5916 VariableSP var_sp (m_die_to_variable_sp[die]); 5917 if (var_sp) 5918 return var_sp; // Already been parsed! 5919 5920 const dw_tag_t tag = die->Tag(); 5921 5922 if ((tag == DW_TAG_variable) || 5923 (tag == DW_TAG_constant) || 5924 (tag == DW_TAG_formal_parameter && sc.function)) 5925 { 5926 DWARFDebugInfoEntry::Attributes attributes; 5927 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 5928 if (num_attributes > 0) 5929 { 5930 const char *name = NULL; 5931 const char *mangled = NULL; 5932 Declaration decl; 5933 uint32_t i; 5934 lldb::user_id_t type_uid = LLDB_INVALID_UID; 5935 DWARFExpression location; 5936 bool is_external = false; 5937 bool is_artificial = false; 5938 bool location_is_const_value_data = false; 5939 AccessType accessibility = eAccessNone; 5940 5941 for (i=0; i<num_attributes; ++i) 5942 { 5943 dw_attr_t attr = attributes.AttributeAtIndex(i); 5944 DWARFFormValue form_value; 5945 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 5946 { 5947 switch (attr) 5948 { 5949 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 5950 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 5951 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 5952 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 5953 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break; 5954 case DW_AT_type: type_uid = form_value.Reference(dwarf_cu); break; 5955 case DW_AT_external: is_external = form_value.Unsigned() != 0; break; 5956 case DW_AT_const_value: 5957 location_is_const_value_data = true; 5958 // Fall through... 5959 case DW_AT_location: 5960 { 5961 if (form_value.BlockData()) 5962 { 5963 const DataExtractor& debug_info_data = get_debug_info_data(); 5964 5965 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 5966 uint32_t block_length = form_value.Unsigned(); 5967 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length); 5968 } 5969 else 5970 { 5971 const DataExtractor& debug_loc_data = get_debug_loc_data(); 5972 const dw_offset_t debug_loc_offset = form_value.Unsigned(); 5973 5974 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset); 5975 if (loc_list_length > 0) 5976 { 5977 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length); 5978 assert (func_low_pc != LLDB_INVALID_ADDRESS); 5979 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress()); 5980 } 5981 } 5982 } 5983 break; 5984 5985 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break; 5986 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 5987 case DW_AT_declaration: 5988 case DW_AT_description: 5989 case DW_AT_endianity: 5990 case DW_AT_segment: 5991 case DW_AT_start_scope: 5992 case DW_AT_visibility: 5993 default: 5994 case DW_AT_abstract_origin: 5995 case DW_AT_sibling: 5996 case DW_AT_specification: 5997 break; 5998 } 5999 } 6000 } 6001 6002 if (location.IsValid()) 6003 { 6004 ValueType scope = eValueTypeInvalid; 6005 6006 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die); 6007 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 6008 SymbolContextScope * symbol_context_scope = NULL; 6009 6010 // DWARF doesn't specify if a DW_TAG_variable is a local, global 6011 // or static variable, so we have to do a little digging by 6012 // looking at the location of a varaible to see if it contains 6013 // a DW_OP_addr opcode _somewhere_ in the definition. I say 6014 // somewhere because clang likes to combine small global variables 6015 // into the same symbol and have locations like: 6016 // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus 6017 // So if we don't have a DW_TAG_formal_parameter, we can look at 6018 // the location to see if it contains a DW_OP_addr opcode, and 6019 // then we can correctly classify our variables. 6020 if (tag == DW_TAG_formal_parameter) 6021 scope = eValueTypeVariableArgument; 6022 else 6023 { 6024 bool op_error = false; 6025 // Check if the location has a DW_OP_addr with any address value... 6026 addr_t location_has_op_addr = false; 6027 if (!location_is_const_value_data) 6028 { 6029 location_has_op_addr = location.LocationContains_DW_OP_addr (LLDB_INVALID_ADDRESS, op_error); 6030 if (op_error) 6031 { 6032 StreamString strm; 6033 location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL); 6034 GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), strm.GetString().c_str()); 6035 } 6036 } 6037 6038 if (location_has_op_addr) 6039 { 6040 if (is_external) 6041 { 6042 scope = eValueTypeVariableGlobal; 6043 6044 if (m_debug_map_symfile) 6045 { 6046 // When leaving the DWARF in the .o files on darwin, 6047 // when we have a global variable that wasn't initialized, 6048 // the .o file might not have allocated a virtual 6049 // address for the global variable. In this case it will 6050 // have created a symbol for the global variable 6051 // that is undefined and external and the value will 6052 // be the byte size of the variable. When we do the 6053 // address map in SymbolFileDWARFDebugMap we rely on 6054 // having an address, we need to do some magic here 6055 // so we can get the correct address for our global 6056 // variable. The address for all of these entries 6057 // will be zero, and there will be an undefined symbol 6058 // in this object file, and the executable will have 6059 // a matching symbol with a good address. So here we 6060 // dig up the correct address and replace it in the 6061 // location for the variable, and set the variable's 6062 // symbol context scope to be that of the main executable 6063 // so the file address will resolve correctly. 6064 if (location.LocationContains_DW_OP_addr (0, op_error)) 6065 { 6066 6067 // we have a possible uninitialized extern global 6068 Symtab *symtab = m_obj_file->GetSymtab(); 6069 if (symtab) 6070 { 6071 ConstString const_name(name); 6072 Symbol *undefined_symbol = symtab->FindFirstSymbolWithNameAndType (const_name, 6073 eSymbolTypeUndefined, 6074 Symtab::eDebugNo, 6075 Symtab::eVisibilityExtern); 6076 6077 if (undefined_symbol) 6078 { 6079 ObjectFile *debug_map_objfile = m_debug_map_symfile->GetObjectFile(); 6080 if (debug_map_objfile) 6081 { 6082 Symtab *debug_map_symtab = debug_map_objfile->GetSymtab(); 6083 Symbol *defined_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name, 6084 eSymbolTypeData, 6085 Symtab::eDebugYes, 6086 Symtab::eVisibilityExtern); 6087 if (defined_symbol) 6088 { 6089 if (defined_symbol->ValueIsAddress()) 6090 { 6091 const addr_t defined_addr = defined_symbol->GetAddress().GetFileAddress(); 6092 if (defined_addr != LLDB_INVALID_ADDRESS) 6093 { 6094 if (location.Update_DW_OP_addr (defined_addr)) 6095 { 6096 symbol_context_scope = defined_symbol; 6097 } 6098 } 6099 } 6100 } 6101 } 6102 } 6103 } 6104 } 6105 } 6106 } 6107 else 6108 { 6109 scope = eValueTypeVariableStatic; 6110 } 6111 } 6112 else 6113 { 6114 scope = eValueTypeVariableLocal; 6115 } 6116 } 6117 6118 if (symbol_context_scope == NULL) 6119 { 6120 switch (parent_tag) 6121 { 6122 case DW_TAG_subprogram: 6123 case DW_TAG_inlined_subroutine: 6124 case DW_TAG_lexical_block: 6125 if (sc.function) 6126 { 6127 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset())); 6128 if (symbol_context_scope == NULL) 6129 symbol_context_scope = sc.function; 6130 } 6131 break; 6132 6133 default: 6134 symbol_context_scope = sc.comp_unit; 6135 break; 6136 } 6137 } 6138 6139 if (symbol_context_scope) 6140 { 6141 var_sp.reset (new Variable (MakeUserID(die->GetOffset()), 6142 name, 6143 mangled, 6144 SymbolFileTypeSP (new SymbolFileType(*this, type_uid)), 6145 scope, 6146 symbol_context_scope, 6147 &decl, 6148 location, 6149 is_external, 6150 is_artificial)); 6151 6152 var_sp->SetLocationIsConstantValueData (location_is_const_value_data); 6153 } 6154 else 6155 { 6156 // Not ready to parse this variable yet. It might be a global 6157 // or static variable that is in a function scope and the function 6158 // in the symbol context wasn't filled in yet 6159 return var_sp; 6160 } 6161 } 6162 } 6163 // Cache var_sp even if NULL (the variable was just a specification or 6164 // was missing vital information to be able to be displayed in the debugger 6165 // (missing location due to optimization, etc)) so we don't re-parse 6166 // this DIE over and over later... 6167 m_die_to_variable_sp[die] = var_sp; 6168 } 6169 return var_sp; 6170} 6171 6172 6173const DWARFDebugInfoEntry * 6174SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset, 6175 dw_offset_t spec_block_die_offset, 6176 DWARFCompileUnit **result_die_cu_handle) 6177{ 6178 // Give the concrete function die specified by "func_die_offset", find the 6179 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points 6180 // to "spec_block_die_offset" 6181 DWARFDebugInfo* info = DebugInfo(); 6182 6183 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle); 6184 if (die) 6185 { 6186 assert (*result_die_cu_handle); 6187 return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle); 6188 } 6189 return NULL; 6190} 6191 6192 6193const DWARFDebugInfoEntry * 6194SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu, 6195 const DWARFDebugInfoEntry *die, 6196 dw_offset_t spec_block_die_offset, 6197 DWARFCompileUnit **result_die_cu_handle) 6198{ 6199 if (die) 6200 { 6201 switch (die->Tag()) 6202 { 6203 case DW_TAG_subprogram: 6204 case DW_TAG_inlined_subroutine: 6205 case DW_TAG_lexical_block: 6206 { 6207 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset) 6208 { 6209 *result_die_cu_handle = dwarf_cu; 6210 return die; 6211 } 6212 6213 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset) 6214 { 6215 *result_die_cu_handle = dwarf_cu; 6216 return die; 6217 } 6218 } 6219 break; 6220 } 6221 6222 // Give the concrete function die specified by "func_die_offset", find the 6223 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points 6224 // to "spec_block_die_offset" 6225 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling()) 6226 { 6227 const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu, 6228 child_die, 6229 spec_block_die_offset, 6230 result_die_cu_handle); 6231 if (result_die) 6232 return result_die; 6233 } 6234 } 6235 6236 *result_die_cu_handle = NULL; 6237 return NULL; 6238} 6239 6240size_t 6241SymbolFileDWARF::ParseVariables 6242( 6243 const SymbolContext& sc, 6244 DWARFCompileUnit* dwarf_cu, 6245 const lldb::addr_t func_low_pc, 6246 const DWARFDebugInfoEntry *orig_die, 6247 bool parse_siblings, 6248 bool parse_children, 6249 VariableList* cc_variable_list 6250) 6251{ 6252 if (orig_die == NULL) 6253 return 0; 6254 6255 VariableListSP variable_list_sp; 6256 6257 size_t vars_added = 0; 6258 const DWARFDebugInfoEntry *die = orig_die; 6259 while (die != NULL) 6260 { 6261 dw_tag_t tag = die->Tag(); 6262 6263 // Check to see if we have already parsed this variable or constant? 6264 if (m_die_to_variable_sp[die]) 6265 { 6266 if (cc_variable_list) 6267 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]); 6268 } 6269 else 6270 { 6271 // We haven't already parsed it, lets do that now. 6272 if ((tag == DW_TAG_variable) || 6273 (tag == DW_TAG_constant) || 6274 (tag == DW_TAG_formal_parameter && sc.function)) 6275 { 6276 if (variable_list_sp.get() == NULL) 6277 { 6278 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die); 6279 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 6280 switch (parent_tag) 6281 { 6282 case DW_TAG_compile_unit: 6283 if (sc.comp_unit != NULL) 6284 { 6285 variable_list_sp = sc.comp_unit->GetVariableList(false); 6286 if (variable_list_sp.get() == NULL) 6287 { 6288 variable_list_sp.reset(new VariableList()); 6289 sc.comp_unit->SetVariableList(variable_list_sp); 6290 } 6291 } 6292 else 6293 { 6294 GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8llx %s with no valid compile unit in symbol context for 0x%8.8llx %s.\n", 6295 MakeUserID(sc_parent_die->GetOffset()), 6296 DW_TAG_value_to_name (parent_tag), 6297 MakeUserID(orig_die->GetOffset()), 6298 DW_TAG_value_to_name (orig_die->Tag())); 6299 } 6300 break; 6301 6302 case DW_TAG_subprogram: 6303 case DW_TAG_inlined_subroutine: 6304 case DW_TAG_lexical_block: 6305 if (sc.function != NULL) 6306 { 6307 // Check to see if we already have parsed the variables for the given scope 6308 6309 Block *block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset())); 6310 if (block == NULL) 6311 { 6312 // This must be a specification or abstract origin with 6313 // a concrete block couterpart in the current function. We need 6314 // to find the concrete block so we can correctly add the 6315 // variable to it 6316 DWARFCompileUnit *concrete_block_die_cu = dwarf_cu; 6317 const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(), 6318 sc_parent_die->GetOffset(), 6319 &concrete_block_die_cu); 6320 if (concrete_block_die) 6321 block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(concrete_block_die->GetOffset())); 6322 } 6323 6324 if (block != NULL) 6325 { 6326 const bool can_create = false; 6327 variable_list_sp = block->GetBlockVariableList (can_create); 6328 if (variable_list_sp.get() == NULL) 6329 { 6330 variable_list_sp.reset(new VariableList()); 6331 block->SetVariableList(variable_list_sp); 6332 } 6333 } 6334 } 6335 break; 6336 6337 default: 6338 GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8llx %s.\n", 6339 MakeUserID(orig_die->GetOffset()), 6340 DW_TAG_value_to_name (orig_die->Tag())); 6341 break; 6342 } 6343 } 6344 6345 if (variable_list_sp) 6346 { 6347 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc)); 6348 if (var_sp) 6349 { 6350 variable_list_sp->AddVariableIfUnique (var_sp); 6351 if (cc_variable_list) 6352 cc_variable_list->AddVariableIfUnique (var_sp); 6353 ++vars_added; 6354 } 6355 } 6356 } 6357 } 6358 6359 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram); 6360 6361 if (!skip_children && parse_children && die->HasChildren()) 6362 { 6363 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list); 6364 } 6365 6366 if (parse_siblings) 6367 die = die->GetSibling(); 6368 else 6369 die = NULL; 6370 } 6371 return vars_added; 6372} 6373 6374//------------------------------------------------------------------ 6375// PluginInterface protocol 6376//------------------------------------------------------------------ 6377const char * 6378SymbolFileDWARF::GetPluginName() 6379{ 6380 return "SymbolFileDWARF"; 6381} 6382 6383const char * 6384SymbolFileDWARF::GetShortPluginName() 6385{ 6386 return GetPluginNameStatic(); 6387} 6388 6389uint32_t 6390SymbolFileDWARF::GetPluginVersion() 6391{ 6392 return 1; 6393} 6394 6395void 6396SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl) 6397{ 6398 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; 6399 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); 6400 if (clang_type) 6401 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); 6402} 6403 6404void 6405SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl) 6406{ 6407 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; 6408 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); 6409 if (clang_type) 6410 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); 6411} 6412 6413void 6414SymbolFileDWARF::DumpIndexes () 6415{ 6416 StreamFile s(stdout, false); 6417 6418 s.Printf ("DWARF index for (%s) '%s/%s':", 6419 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(), 6420 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(), 6421 GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 6422 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s); 6423 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s); 6424 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s); 6425 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s); 6426 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s); 6427 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s); 6428 s.Printf("\nTypes:\n"); m_type_index.Dump (&s); 6429 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s); 6430} 6431 6432void 6433SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context, 6434 const char *name, 6435 llvm::SmallVectorImpl <clang::NamedDecl *> *results) 6436{ 6437 DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context); 6438 6439 if (iter == m_decl_ctx_to_die.end()) 6440 return; 6441 6442 for (DIEPointerSet::iterator pos = iter->second.begin(), end = iter->second.end(); pos != end; ++pos) 6443 { 6444 const DWARFDebugInfoEntry *context_die = *pos; 6445 6446 if (!results) 6447 return; 6448 6449 DWARFDebugInfo* info = DebugInfo(); 6450 6451 DIEArray die_offsets; 6452 6453 DWARFCompileUnit* dwarf_cu = NULL; 6454 const DWARFDebugInfoEntry* die = NULL; 6455 6456 if (m_using_apple_tables) 6457 { 6458 if (m_apple_types_ap.get()) 6459 m_apple_types_ap->FindByName (name, die_offsets); 6460 } 6461 else 6462 { 6463 if (!m_indexed) 6464 Index (); 6465 6466 m_type_index.Find (ConstString(name), die_offsets); 6467 } 6468 6469 const size_t num_matches = die_offsets.size(); 6470 6471 if (num_matches) 6472 { 6473 for (size_t i = 0; i < num_matches; ++i) 6474 { 6475 const dw_offset_t die_offset = die_offsets[i]; 6476 die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); 6477 6478 if (die->GetParent() != context_die) 6479 continue; 6480 6481 Type *matching_type = ResolveType (dwarf_cu, die); 6482 6483 lldb::clang_type_t type = matching_type->GetClangForwardType(); 6484 clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type); 6485 6486 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr())) 6487 { 6488 clang::TagDecl *tag_decl = tag_type->getDecl(); 6489 results->push_back(tag_decl); 6490 } 6491 else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr())) 6492 { 6493 clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); 6494 results->push_back(typedef_decl); 6495 } 6496 } 6497 } 6498 } 6499} 6500 6501void 6502SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton, 6503 const clang::DeclContext *decl_context, 6504 clang::DeclarationName decl_name, 6505 llvm::SmallVectorImpl <clang::NamedDecl *> *results) 6506{ 6507 6508 switch (decl_context->getDeclKind()) 6509 { 6510 case clang::Decl::Namespace: 6511 case clang::Decl::TranslationUnit: 6512 { 6513 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; 6514 symbol_file_dwarf->SearchDeclContext (decl_context, decl_name.getAsString().c_str(), results); 6515 } 6516 break; 6517 default: 6518 break; 6519 } 6520} 6521 6522bool 6523SymbolFileDWARF::LayoutRecordType (void *baton, 6524 const clang::RecordDecl *record_decl, 6525 uint64_t &size, 6526 uint64_t &alignment, 6527 llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets, 6528 llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, 6529 llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) 6530{ 6531 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; 6532 return symbol_file_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets); 6533} 6534 6535 6536bool 6537SymbolFileDWARF::LayoutRecordType (const clang::RecordDecl *record_decl, 6538 uint64_t &bit_size, 6539 uint64_t &alignment, 6540 llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets, 6541 llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, 6542 llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) 6543{ 6544 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); 6545 RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find (record_decl); 6546 bool success = false; 6547 base_offsets.clear(); 6548 vbase_offsets.clear(); 6549 if (pos != m_record_decl_to_layout_map.end()) 6550 { 6551 bit_size = pos->second.bit_size; 6552 alignment = pos->second.alignment; 6553 field_offsets.swap(pos->second.field_offsets); 6554 m_record_decl_to_layout_map.erase(pos); 6555 success = true; 6556 } 6557 else 6558 { 6559 bit_size = 0; 6560 alignment = 0; 6561 field_offsets.clear(); 6562 } 6563 6564 if (log) 6565 GetObjectFile()->GetModule()->LogMessage (log.get(), 6566 "SymbolFileDWARF::LayoutRecordType (record_decl = %p, bit_size = %llu, alignment = %llu, field_offsets[%u],base_offsets[%u], vbase_offsets[%u]) success = %i", 6567 record_decl, 6568 bit_size, 6569 alignment, 6570 (uint32_t)field_offsets.size(), 6571 (uint32_t)base_offsets.size(), 6572 (uint32_t)vbase_offsets.size(), 6573 success); 6574 return success; 6575} 6576 6577 6578 6579