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/Basic/Builtins.h" 18 #include "clang/Basic/IdentifierTable.h" 19 #include "clang/Basic/LangOptions.h" 20 #include "clang/Basic/SourceManager.h" 21 #include "clang/Basic/TargetInfo.h" 22 #include "clang/Basic/Specifiers.h" 23 #include "clang/Sema/DeclSpec.h" 24 25 #include "llvm/Support/Casting.h" 26 27 #include "lldb/Core/Module.h" 28 #include "lldb/Core/PluginManager.h" 29 #include "lldb/Core/RegularExpression.h" 30 #include "lldb/Core/Scalar.h" 31 #include "lldb/Core/Section.h" 32 #include "lldb/Core/StreamFile.h" 33 #include "lldb/Core/Timer.h" 34 #include "lldb/Core/Value.h" 35 36 #include "lldb/Symbol/Block.h" 37 #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h" 38 #include "lldb/Symbol/CompileUnit.h" 39 #include "lldb/Symbol/LineTable.h" 40 #include "lldb/Symbol/ObjectFile.h" 41 #include "lldb/Symbol/SymbolVendor.h" 42 #include "lldb/Symbol/VariableList.h" 43 44 #include "DWARFCompileUnit.h" 45 #include "DWARFDebugAbbrev.h" 46 #include "DWARFDebugAranges.h" 47 #include "DWARFDebugInfo.h" 48 #include "DWARFDebugInfoEntry.h" 49 #include "DWARFDebugLine.h" 50 #include "DWARFDebugPubnames.h" 51 #include "DWARFDebugRanges.h" 52 #include "DWARFDIECollection.h" 53 #include "DWARFFormValue.h" 54 #include "DWARFLocationList.h" 55 #include "LogChannelDWARF.h" 56 #include "SymbolFileDWARFDebugMap.h" 57 58 #include <map> 59 60 //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN 61 62 #ifdef ENABLE_DEBUG_PRINTF 63 #include <stdio.h> 64 #define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__) 65 #else 66 #define DEBUG_PRINTF(fmt, ...) 67 #endif 68 69 #define DIE_IS_BEING_PARSED ((lldb_private::Type*)1) 70 71 using namespace lldb; 72 using namespace lldb_private; 73 74 75 static AccessType 76 DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility) 77 { 78 switch (dwarf_accessibility) 79 { 80 case DW_ACCESS_public: return eAccessPublic; 81 case DW_ACCESS_private: return eAccessPrivate; 82 case DW_ACCESS_protected: return eAccessProtected; 83 default: break; 84 } 85 return eAccessNone; 86 } 87 88 void 89 SymbolFileDWARF::Initialize() 90 { 91 LogChannelDWARF::Initialize(); 92 PluginManager::RegisterPlugin (GetPluginNameStatic(), 93 GetPluginDescriptionStatic(), 94 CreateInstance); 95 } 96 97 void 98 SymbolFileDWARF::Terminate() 99 { 100 PluginManager::UnregisterPlugin (CreateInstance); 101 LogChannelDWARF::Initialize(); 102 } 103 104 105 const char * 106 SymbolFileDWARF::GetPluginNameStatic() 107 { 108 return "symbol-file.dwarf2"; 109 } 110 111 const char * 112 SymbolFileDWARF::GetPluginDescriptionStatic() 113 { 114 return "DWARF and DWARF3 debug symbol file reader."; 115 } 116 117 118 SymbolFile* 119 SymbolFileDWARF::CreateInstance (ObjectFile* obj_file) 120 { 121 return new SymbolFileDWARF(obj_file); 122 } 123 124 TypeList * 125 SymbolFileDWARF::GetTypeList () 126 { 127 if (m_debug_map_symfile) 128 return m_debug_map_symfile->GetTypeList(); 129 return m_obj_file->GetModule()->GetTypeList(); 130 131 } 132 133 //---------------------------------------------------------------------- 134 // Gets the first parent that is a lexical block, function or inlined 135 // subroutine, or compile unit. 136 //---------------------------------------------------------------------- 137 static const DWARFDebugInfoEntry * 138 GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die) 139 { 140 const DWARFDebugInfoEntry *die; 141 for (die = child_die->GetParent(); die != NULL; die = die->GetParent()) 142 { 143 dw_tag_t tag = die->Tag(); 144 145 switch (tag) 146 { 147 case DW_TAG_compile_unit: 148 case DW_TAG_subprogram: 149 case DW_TAG_inlined_subroutine: 150 case DW_TAG_lexical_block: 151 return die; 152 } 153 } 154 return NULL; 155 } 156 157 158 SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) : 159 SymbolFile (objfile), 160 m_debug_map_symfile (NULL), 161 m_clang_tu_decl (NULL), 162 m_flags(), 163 m_data_debug_abbrev(), 164 m_data_debug_frame(), 165 m_data_debug_info(), 166 m_data_debug_line(), 167 m_data_debug_loc(), 168 m_data_debug_ranges(), 169 m_data_debug_str(), 170 m_abbr(), 171 m_aranges(), 172 m_info(), 173 m_line(), 174 m_function_basename_index(), 175 m_function_fullname_index(), 176 m_function_method_index(), 177 m_function_selector_index(), 178 m_objc_class_selectors_index(), 179 m_global_index(), 180 m_type_index(), 181 m_namespace_index(), 182 m_indexed (false), 183 m_is_external_ast_source (false), 184 m_ranges(), 185 m_unique_ast_type_map () 186 { 187 } 188 189 SymbolFileDWARF::~SymbolFileDWARF() 190 { 191 if (m_is_external_ast_source) 192 m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource (); 193 } 194 195 static const ConstString & 196 GetDWARFMachOSegmentName () 197 { 198 static ConstString g_dwarf_section_name ("__DWARF"); 199 return g_dwarf_section_name; 200 } 201 202 UniqueDWARFASTTypeMap & 203 SymbolFileDWARF::GetUniqueDWARFASTTypeMap () 204 { 205 if (m_debug_map_symfile) 206 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap (); 207 return m_unique_ast_type_map; 208 } 209 210 ClangASTContext & 211 SymbolFileDWARF::GetClangASTContext () 212 { 213 if (m_debug_map_symfile) 214 return m_debug_map_symfile->GetClangASTContext (); 215 216 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext(); 217 if (!m_is_external_ast_source) 218 { 219 m_is_external_ast_source = true; 220 llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap ( 221 new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl, 222 SymbolFileDWARF::CompleteObjCInterfaceDecl, 223 SymbolFileDWARF::FindExternalVisibleDeclsByName, 224 this)); 225 226 ast.SetExternalSource (ast_source_ap); 227 } 228 return ast; 229 } 230 231 void 232 SymbolFileDWARF::InitializeObject() 233 { 234 // Install our external AST source callbacks so we can complete Clang types. 235 Module *module = m_obj_file->GetModule(); 236 if (module) 237 { 238 const SectionList *section_list = m_obj_file->GetSectionList(); 239 240 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get(); 241 242 // Memory map the DWARF mach-o segment so we have everything mmap'ed 243 // to keep our heap memory usage down. 244 if (section) 245 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data); 246 } 247 } 248 249 bool 250 SymbolFileDWARF::SupportedVersion(uint16_t version) 251 { 252 return version == 2 || version == 3; 253 } 254 255 uint32_t 256 SymbolFileDWARF::GetAbilities () 257 { 258 uint32_t abilities = 0; 259 if (m_obj_file != NULL) 260 { 261 const Section* section = NULL; 262 const SectionList *section_list = m_obj_file->GetSectionList(); 263 if (section_list == NULL) 264 return 0; 265 266 uint64_t debug_abbrev_file_size = 0; 267 uint64_t debug_aranges_file_size = 0; 268 uint64_t debug_frame_file_size = 0; 269 uint64_t debug_info_file_size = 0; 270 uint64_t debug_line_file_size = 0; 271 uint64_t debug_loc_file_size = 0; 272 uint64_t debug_macinfo_file_size = 0; 273 uint64_t debug_pubnames_file_size = 0; 274 uint64_t debug_pubtypes_file_size = 0; 275 uint64_t debug_ranges_file_size = 0; 276 uint64_t debug_str_file_size = 0; 277 278 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get(); 279 280 if (section) 281 section_list = §ion->GetChildren (); 282 283 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get(); 284 if (section != NULL) 285 { 286 debug_info_file_size = section->GetByteSize(); 287 288 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get(); 289 if (section) 290 debug_abbrev_file_size = section->GetByteSize(); 291 else 292 m_flags.Set (flagsGotDebugAbbrevData); 293 294 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get(); 295 if (section) 296 debug_aranges_file_size = section->GetByteSize(); 297 else 298 m_flags.Set (flagsGotDebugArangesData); 299 300 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get(); 301 if (section) 302 debug_frame_file_size = section->GetByteSize(); 303 else 304 m_flags.Set (flagsGotDebugFrameData); 305 306 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get(); 307 if (section) 308 debug_line_file_size = section->GetByteSize(); 309 else 310 m_flags.Set (flagsGotDebugLineData); 311 312 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get(); 313 if (section) 314 debug_loc_file_size = section->GetByteSize(); 315 else 316 m_flags.Set (flagsGotDebugLocData); 317 318 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get(); 319 if (section) 320 debug_macinfo_file_size = section->GetByteSize(); 321 else 322 m_flags.Set (flagsGotDebugMacInfoData); 323 324 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get(); 325 if (section) 326 debug_pubnames_file_size = section->GetByteSize(); 327 else 328 m_flags.Set (flagsGotDebugPubNamesData); 329 330 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get(); 331 if (section) 332 debug_pubtypes_file_size = section->GetByteSize(); 333 else 334 m_flags.Set (flagsGotDebugPubTypesData); 335 336 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get(); 337 if (section) 338 debug_ranges_file_size = section->GetByteSize(); 339 else 340 m_flags.Set (flagsGotDebugRangesData); 341 342 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get(); 343 if (section) 344 debug_str_file_size = section->GetByteSize(); 345 else 346 m_flags.Set (flagsGotDebugStrData); 347 } 348 349 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0) 350 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes; 351 352 if (debug_line_file_size > 0) 353 abilities |= LineTables; 354 355 if (debug_aranges_file_size > 0) 356 abilities |= AddressAcceleratorTable; 357 358 if (debug_pubnames_file_size > 0) 359 abilities |= FunctionAcceleratorTable; 360 361 if (debug_pubtypes_file_size > 0) 362 abilities |= TypeAcceleratorTable; 363 364 if (debug_macinfo_file_size > 0) 365 abilities |= MacroInformation; 366 367 if (debug_frame_file_size > 0) 368 abilities |= CallFrameInformation; 369 } 370 return abilities; 371 } 372 373 const DataExtractor& 374 SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data) 375 { 376 if (m_flags.IsClear (got_flag)) 377 { 378 m_flags.Set (got_flag); 379 const SectionList *section_list = m_obj_file->GetSectionList(); 380 if (section_list) 381 { 382 Section *section = section_list->FindSectionByType(sect_type, true).get(); 383 if (section) 384 { 385 // See if we memory mapped the DWARF segment? 386 if (m_dwarf_data.GetByteSize()) 387 { 388 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize()); 389 } 390 else 391 { 392 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0) 393 data.Clear(); 394 } 395 } 396 } 397 } 398 return data; 399 } 400 401 const DataExtractor& 402 SymbolFileDWARF::get_debug_abbrev_data() 403 { 404 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev); 405 } 406 407 const DataExtractor& 408 SymbolFileDWARF::get_debug_frame_data() 409 { 410 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame); 411 } 412 413 const DataExtractor& 414 SymbolFileDWARF::get_debug_info_data() 415 { 416 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info); 417 } 418 419 const DataExtractor& 420 SymbolFileDWARF::get_debug_line_data() 421 { 422 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line); 423 } 424 425 const DataExtractor& 426 SymbolFileDWARF::get_debug_loc_data() 427 { 428 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc); 429 } 430 431 const DataExtractor& 432 SymbolFileDWARF::get_debug_ranges_data() 433 { 434 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges); 435 } 436 437 const DataExtractor& 438 SymbolFileDWARF::get_debug_str_data() 439 { 440 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str); 441 } 442 443 444 DWARFDebugAbbrev* 445 SymbolFileDWARF::DebugAbbrev() 446 { 447 if (m_abbr.get() == NULL) 448 { 449 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data(); 450 if (debug_abbrev_data.GetByteSize() > 0) 451 { 452 m_abbr.reset(new DWARFDebugAbbrev()); 453 if (m_abbr.get()) 454 m_abbr->Parse(debug_abbrev_data); 455 } 456 } 457 return m_abbr.get(); 458 } 459 460 const DWARFDebugAbbrev* 461 SymbolFileDWARF::DebugAbbrev() const 462 { 463 return m_abbr.get(); 464 } 465 466 DWARFDebugAranges* 467 SymbolFileDWARF::DebugAranges() 468 { 469 // It turns out that llvm-gcc doesn't generate .debug_aranges in .o files 470 // and we are already parsing all of the DWARF because the .debug_pubnames 471 // is useless (it only mentions symbols that are externally visible), so 472 // don't use the .debug_aranges section, we should be using a debug aranges 473 // we got from SymbolFileDWARF::Index(). 474 475 if (!m_indexed) 476 Index(); 477 478 479 // if (m_aranges.get() == NULL) 480 // { 481 // Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 482 // m_aranges.reset(new DWARFDebugAranges()); 483 // if (m_aranges.get()) 484 // { 485 // const DataExtractor &debug_aranges_data = get_debug_aranges_data(); 486 // if (debug_aranges_data.GetByteSize() > 0) 487 // m_aranges->Extract(debug_aranges_data); 488 // else 489 // m_aranges->Generate(this); 490 // } 491 // } 492 return m_aranges.get(); 493 } 494 495 const DWARFDebugAranges* 496 SymbolFileDWARF::DebugAranges() const 497 { 498 return m_aranges.get(); 499 } 500 501 502 DWARFDebugInfo* 503 SymbolFileDWARF::DebugInfo() 504 { 505 if (m_info.get() == NULL) 506 { 507 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 508 if (get_debug_info_data().GetByteSize() > 0) 509 { 510 m_info.reset(new DWARFDebugInfo()); 511 if (m_info.get()) 512 { 513 m_info->SetDwarfData(this); 514 } 515 } 516 } 517 return m_info.get(); 518 } 519 520 const DWARFDebugInfo* 521 SymbolFileDWARF::DebugInfo() const 522 { 523 return m_info.get(); 524 } 525 526 DWARFCompileUnit* 527 SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid) 528 { 529 DWARFDebugInfo* info = DebugInfo(); 530 if (info) 531 return info->GetCompileUnit(cu_uid).get(); 532 return NULL; 533 } 534 535 536 DWARFDebugRanges* 537 SymbolFileDWARF::DebugRanges() 538 { 539 if (m_ranges.get() == NULL) 540 { 541 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this); 542 if (get_debug_ranges_data().GetByteSize() > 0) 543 { 544 m_ranges.reset(new DWARFDebugRanges()); 545 if (m_ranges.get()) 546 m_ranges->Extract(this); 547 } 548 } 549 return m_ranges.get(); 550 } 551 552 const DWARFDebugRanges* 553 SymbolFileDWARF::DebugRanges() const 554 { 555 return m_ranges.get(); 556 } 557 558 bool 559 SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp) 560 { 561 if (curr_cu != NULL) 562 { 563 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly (); 564 if (cu_die) 565 { 566 const char * cu_die_name = cu_die->GetName(this, curr_cu); 567 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL); 568 LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0); 569 if (cu_die_name) 570 { 571 FileSpec cu_file_spec; 572 573 if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0') 574 { 575 // If we have a full path to the compile unit, we don't need to resolve 576 // the file. This can be expensive e.g. when the source files are NFS mounted. 577 cu_file_spec.SetFile (cu_die_name, false); 578 } 579 else 580 { 581 std::string fullpath(cu_comp_dir); 582 if (*fullpath.rbegin() != '/') 583 fullpath += '/'; 584 fullpath += cu_die_name; 585 cu_file_spec.SetFile (fullpath.c_str(), false); 586 } 587 588 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), curr_cu, cu_file_spec, curr_cu->GetOffset(), class_language)); 589 if (compile_unit_sp.get()) 590 { 591 curr_cu->SetUserData(compile_unit_sp.get()); 592 return true; 593 } 594 } 595 } 596 } 597 return false; 598 } 599 600 uint32_t 601 SymbolFileDWARF::GetNumCompileUnits() 602 { 603 DWARFDebugInfo* info = DebugInfo(); 604 if (info) 605 return info->GetNumCompileUnits(); 606 return 0; 607 } 608 609 CompUnitSP 610 SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) 611 { 612 CompUnitSP comp_unit; 613 DWARFDebugInfo* info = DebugInfo(); 614 if (info) 615 { 616 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx); 617 if (curr_cu != NULL) 618 { 619 // Our symbol vendor shouldn't be asking us to add a compile unit that 620 // has already been added to it, which this DWARF plug-in knows as it 621 // stores the lldb compile unit (CompileUnit) pointer in each 622 // DWARFCompileUnit object when it gets added. 623 assert(curr_cu->GetUserData() == NULL); 624 ParseCompileUnit(curr_cu, comp_unit); 625 } 626 } 627 return comp_unit; 628 } 629 630 static void 631 AddRangesToBlock 632 ( 633 Block& block, 634 DWARFDebugRanges::RangeList& ranges, 635 addr_t block_base_addr 636 ) 637 { 638 ranges.SubtractOffset (block_base_addr); 639 size_t range_idx = 0; 640 const DWARFDebugRanges::Range *debug_range; 641 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++) 642 { 643 block.AddRange(debug_range->begin_offset, debug_range->end_offset); 644 } 645 } 646 647 648 Function * 649 SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die) 650 { 651 DWARFDebugRanges::RangeList func_ranges; 652 const char *name = NULL; 653 const char *mangled = NULL; 654 int decl_file = 0; 655 int decl_line = 0; 656 int decl_column = 0; 657 int call_file = 0; 658 int call_line = 0; 659 int call_column = 0; 660 DWARFExpression frame_base; 661 662 assert (die->Tag() == DW_TAG_subprogram); 663 664 if (die->Tag() != DW_TAG_subprogram) 665 return NULL; 666 667 const DWARFDebugInfoEntry *parent_die = die->GetParent(); 668 switch (parent_die->Tag()) 669 { 670 case DW_TAG_structure_type: 671 case DW_TAG_class_type: 672 // We have methods of a class or struct 673 { 674 Type *class_type = ResolveType (dwarf_cu, parent_die); 675 if (class_type) 676 class_type->GetClangFullType(); 677 } 678 break; 679 680 default: 681 // Parse the function prototype as a type that can then be added to concrete function instance 682 ParseTypes (sc, dwarf_cu, die, false, false); 683 break; 684 } 685 686 //FixupTypes(); 687 688 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base)) 689 { 690 // Union of all ranges in the function DIE (if the function is discontiguous) 691 AddressRange func_range; 692 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0); 693 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0); 694 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr) 695 { 696 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList()); 697 if (func_range.GetBaseAddress().IsValid()) 698 func_range.SetByteSize(highest_func_addr - lowest_func_addr); 699 } 700 701 if (func_range.GetBaseAddress().IsValid()) 702 { 703 Mangled func_name; 704 if (mangled) 705 func_name.SetValue(mangled, true); 706 else if (name) 707 func_name.SetValue(name, false); 708 709 FunctionSP func_sp; 710 std::auto_ptr<Declaration> decl_ap; 711 if (decl_file != 0 || decl_line != 0 || decl_column != 0) 712 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), 713 decl_line, 714 decl_column)); 715 716 Type *func_type = m_die_to_type.lookup (die); 717 718 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED); 719 720 func_range.GetBaseAddress().ResolveLinkedAddress(); 721 722 func_sp.reset(new Function (sc.comp_unit, 723 die->GetOffset(), // UserID is the DIE offset 724 die->GetOffset(), 725 func_name, 726 func_type, 727 func_range)); // first address range 728 729 if (func_sp.get() != NULL) 730 { 731 func_sp->GetFrameBaseExpression() = frame_base; 732 sc.comp_unit->AddFunction(func_sp); 733 return func_sp.get(); 734 } 735 } 736 } 737 return NULL; 738 } 739 740 size_t 741 SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) 742 { 743 assert (sc.comp_unit); 744 size_t functions_added = 0; 745 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 746 if (dwarf_cu) 747 { 748 DWARFDIECollection function_dies; 749 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies); 750 size_t func_idx; 751 for (func_idx = 0; func_idx < num_funtions; ++func_idx) 752 { 753 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx); 754 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL) 755 { 756 if (ParseCompileUnitFunction(sc, dwarf_cu, die)) 757 ++functions_added; 758 } 759 } 760 //FixupTypes(); 761 } 762 return functions_added; 763 } 764 765 bool 766 SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) 767 { 768 assert (sc.comp_unit); 769 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 770 assert (curr_cu); 771 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly(); 772 773 if (cu_die) 774 { 775 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL); 776 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_stmt_list, DW_INVALID_OFFSET); 777 778 // All file indexes in DWARF are one based and a file of index zero is 779 // supposed to be the compile unit itself. 780 support_files.Append (*sc.comp_unit); 781 782 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files); 783 } 784 return false; 785 } 786 787 struct ParseDWARFLineTableCallbackInfo 788 { 789 LineTable* line_table; 790 const SectionList *section_list; 791 lldb::addr_t prev_sect_file_base_addr; 792 lldb::addr_t curr_sect_file_base_addr; 793 bool is_oso_for_debug_map; 794 bool prev_in_final_executable; 795 DWARFDebugLine::Row prev_row; 796 SectionSP prev_section_sp; 797 SectionSP curr_section_sp; 798 }; 799 800 //---------------------------------------------------------------------- 801 // ParseStatementTableCallback 802 //---------------------------------------------------------------------- 803 static void 804 ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData) 805 { 806 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table; 807 if (state.row == DWARFDebugLine::State::StartParsingLineTable) 808 { 809 // Just started parsing the line table 810 } 811 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable) 812 { 813 // Done parsing line table, nothing to do for the cleanup 814 } 815 else 816 { 817 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData; 818 // We have a new row, lets append it 819 820 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false) 821 { 822 info->prev_section_sp = info->curr_section_sp; 823 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr; 824 // If this is an end sequence entry, then we subtract one from the 825 // address to make sure we get an address that is not the end of 826 // a section. 827 if (state.end_sequence && state.address != 0) 828 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1); 829 else 830 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address); 831 832 if (info->curr_section_sp.get()) 833 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress (); 834 else 835 info->curr_sect_file_base_addr = 0; 836 } 837 if (info->curr_section_sp.get()) 838 { 839 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr; 840 // Check for the fancy section magic to determine if we 841 842 if (info->is_oso_for_debug_map) 843 { 844 // When this is a debug map object file that contains DWARF 845 // (referenced from an N_OSO debug map nlist entry) we will have 846 // a file address in the file range for our section from the 847 // original .o file, and a load address in the executable that 848 // contains the debug map. 849 // 850 // If the sections for the file range and load range are 851 // different, we have a remapped section for the function and 852 // this address is resolved. If they are the same, then the 853 // function for this address didn't make it into the final 854 // executable. 855 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL; 856 857 // If we are doing DWARF with debug map, then we need to carefully 858 // add each line table entry as there may be gaps as functions 859 // get moved around or removed. 860 if (!info->prev_row.end_sequence && info->prev_section_sp.get()) 861 { 862 if (info->prev_in_final_executable) 863 { 864 bool terminate_previous_entry = false; 865 if (!curr_in_final_executable) 866 { 867 // Check for the case where the previous line entry 868 // in a function made it into the final executable, 869 // yet the current line entry falls in a function 870 // that didn't. The line table used to be contiguous 871 // through this address range but now it isn't. We 872 // need to terminate the previous line entry so 873 // that we can reconstruct the line range correctly 874 // for it and to keep the line table correct. 875 terminate_previous_entry = true; 876 } 877 else if (info->curr_section_sp.get() != info->prev_section_sp.get()) 878 { 879 // Check for cases where the line entries used to be 880 // contiguous address ranges, but now they aren't. 881 // This can happen when order files specify the 882 // ordering of the functions. 883 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr; 884 Section *curr_sect = info->curr_section_sp.get(); 885 Section *prev_sect = info->prev_section_sp.get(); 886 assert (curr_sect->GetLinkedSection()); 887 assert (prev_sect->GetLinkedSection()); 888 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address; 889 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset; 890 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset; 891 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr; 892 if (object_file_addr_delta != linked_file_addr_delta) 893 terminate_previous_entry = true; 894 } 895 896 if (terminate_previous_entry) 897 { 898 line_table->InsertLineEntry (info->prev_section_sp, 899 state.address - info->prev_sect_file_base_addr, 900 info->prev_row.line, 901 info->prev_row.column, 902 info->prev_row.file, 903 false, // is_stmt 904 false, // basic_block 905 false, // state.prologue_end 906 false, // state.epilogue_begin 907 true); // end_sequence); 908 } 909 } 910 } 911 912 if (curr_in_final_executable) 913 { 914 line_table->InsertLineEntry (info->curr_section_sp, 915 curr_line_section_offset, 916 state.line, 917 state.column, 918 state.file, 919 state.is_stmt, 920 state.basic_block, 921 state.prologue_end, 922 state.epilogue_begin, 923 state.end_sequence); 924 info->prev_section_sp = info->curr_section_sp; 925 } 926 else 927 { 928 // If the current address didn't make it into the final 929 // executable, the current section will be the __text 930 // segment in the .o file, so we need to clear this so 931 // we can catch the next function that did make it into 932 // the final executable. 933 info->prev_section_sp.reset(); 934 info->curr_section_sp.reset(); 935 } 936 937 info->prev_in_final_executable = curr_in_final_executable; 938 } 939 else 940 { 941 // We are not in an object file that contains DWARF for an 942 // N_OSO, this is just a normal DWARF file. The DWARF spec 943 // guarantees that the addresses will be in increasing order 944 // so, since we store line tables in file address order, we 945 // can always just append the line entry without needing to 946 // search for the correct insertion point (we don't need to 947 // use LineEntry::InsertLineEntry()). 948 line_table->AppendLineEntry (info->curr_section_sp, 949 curr_line_section_offset, 950 state.line, 951 state.column, 952 state.file, 953 state.is_stmt, 954 state.basic_block, 955 state.prologue_end, 956 state.epilogue_begin, 957 state.end_sequence); 958 } 959 } 960 961 info->prev_row = state; 962 } 963 } 964 965 bool 966 SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc) 967 { 968 assert (sc.comp_unit); 969 if (sc.comp_unit->GetLineTable() != NULL) 970 return true; 971 972 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 973 if (dwarf_cu) 974 { 975 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly(); 976 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET); 977 if (cu_line_offset != DW_INVALID_OFFSET) 978 { 979 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit)); 980 if (line_table_ap.get()) 981 { 982 ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_debug_map_symfile != NULL, false}; 983 uint32_t offset = cu_line_offset; 984 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info); 985 sc.comp_unit->SetLineTable(line_table_ap.release()); 986 return true; 987 } 988 } 989 } 990 return false; 991 } 992 993 size_t 994 SymbolFileDWARF::ParseFunctionBlocks 995 ( 996 const SymbolContext& sc, 997 Block *parent_block, 998 DWARFCompileUnit* dwarf_cu, 999 const DWARFDebugInfoEntry *die, 1000 addr_t subprogram_low_pc, 1001 bool parse_siblings, 1002 bool parse_children 1003 ) 1004 { 1005 size_t blocks_added = 0; 1006 while (die != NULL) 1007 { 1008 dw_tag_t tag = die->Tag(); 1009 1010 switch (tag) 1011 { 1012 case DW_TAG_inlined_subroutine: 1013 case DW_TAG_subprogram: 1014 case DW_TAG_lexical_block: 1015 { 1016 DWARFDebugRanges::RangeList ranges; 1017 const char *name = NULL; 1018 const char *mangled_name = NULL; 1019 Block *block = NULL; 1020 if (tag != DW_TAG_subprogram) 1021 { 1022 BlockSP block_sp(new Block (die->GetOffset())); 1023 parent_block->AddChild(block_sp); 1024 block = block_sp.get(); 1025 } 1026 else 1027 { 1028 block = parent_block; 1029 } 1030 1031 int decl_file = 0; 1032 int decl_line = 0; 1033 int decl_column = 0; 1034 int call_file = 0; 1035 int call_line = 0; 1036 int call_column = 0; 1037 if (die->GetDIENamesAndRanges (this, 1038 dwarf_cu, 1039 name, 1040 mangled_name, 1041 ranges, 1042 decl_file, decl_line, decl_column, 1043 call_file, call_line, call_column)) 1044 { 1045 if (tag == DW_TAG_subprogram) 1046 { 1047 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS); 1048 subprogram_low_pc = ranges.LowestAddress(0); 1049 } 1050 else if (tag == DW_TAG_inlined_subroutine) 1051 { 1052 // We get called here for inlined subroutines in two ways. 1053 // The first time is when we are making the Function object 1054 // for this inlined concrete instance. Since we're creating a top level block at 1055 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to 1056 // adjust the containing address. 1057 // The second time is when we are parsing the blocks inside the function that contains 1058 // the inlined concrete instance. Since these will be blocks inside the containing "real" 1059 // function the offset will be for that function. 1060 if (subprogram_low_pc == LLDB_INVALID_ADDRESS) 1061 { 1062 subprogram_low_pc = ranges.LowestAddress(0); 1063 } 1064 } 1065 1066 AddRangesToBlock (*block, ranges, subprogram_low_pc); 1067 1068 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL)) 1069 { 1070 std::auto_ptr<Declaration> decl_ap; 1071 if (decl_file != 0 || decl_line != 0 || decl_column != 0) 1072 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), 1073 decl_line, decl_column)); 1074 1075 std::auto_ptr<Declaration> call_ap; 1076 if (call_file != 0 || call_line != 0 || call_column != 0) 1077 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), 1078 call_line, call_column)); 1079 1080 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get()); 1081 } 1082 1083 ++blocks_added; 1084 1085 if (parse_children && die->HasChildren()) 1086 { 1087 blocks_added += ParseFunctionBlocks (sc, 1088 block, 1089 dwarf_cu, 1090 die->GetFirstChild(), 1091 subprogram_low_pc, 1092 true, 1093 true); 1094 } 1095 } 1096 } 1097 break; 1098 default: 1099 break; 1100 } 1101 1102 if (parse_siblings) 1103 die = die->GetSibling(); 1104 else 1105 die = NULL; 1106 } 1107 return blocks_added; 1108 } 1109 1110 size_t 1111 SymbolFileDWARF::ParseChildMembers 1112 ( 1113 const SymbolContext& sc, 1114 DWARFCompileUnit* dwarf_cu, 1115 const DWARFDebugInfoEntry *parent_die, 1116 clang_type_t class_clang_type, 1117 const LanguageType class_language, 1118 std::vector<clang::CXXBaseSpecifier *>& base_classes, 1119 std::vector<int>& member_accessibilities, 1120 DWARFDIECollection& member_function_dies, 1121 AccessType& default_accessibility, 1122 bool &is_a_class 1123 ) 1124 { 1125 if (parent_die == NULL) 1126 return 0; 1127 1128 size_t count = 0; 1129 const DWARFDebugInfoEntry *die; 1130 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 1131 uint32_t member_idx = 0; 1132 1133 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 1134 { 1135 dw_tag_t tag = die->Tag(); 1136 1137 switch (tag) 1138 { 1139 case DW_TAG_member: 1140 { 1141 DWARFDebugInfoEntry::Attributes attributes; 1142 const size_t num_attributes = die->GetAttributes (this, 1143 dwarf_cu, 1144 fixed_form_sizes, 1145 attributes); 1146 if (num_attributes > 0) 1147 { 1148 Declaration decl; 1149 //DWARFExpression location; 1150 const char *name = NULL; 1151 bool is_artificial = false; 1152 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 1153 AccessType accessibility = eAccessNone; 1154 //off_t member_offset = 0; 1155 size_t byte_size = 0; 1156 size_t bit_offset = 0; 1157 size_t bit_size = 0; 1158 uint32_t i; 1159 for (i=0; i<num_attributes && !is_artificial; ++i) 1160 { 1161 const dw_attr_t attr = attributes.AttributeAtIndex(i); 1162 DWARFFormValue form_value; 1163 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 1164 { 1165 switch (attr) 1166 { 1167 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 1168 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 1169 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 1170 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 1171 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 1172 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break; 1173 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break; 1174 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break; 1175 case DW_AT_data_member_location: 1176 // if (form_value.BlockData()) 1177 // { 1178 // Value initialValue(0); 1179 // Value memberOffset(0); 1180 // const DataExtractor& debug_info_data = get_debug_info_data(); 1181 // uint32_t block_length = form_value.Unsigned(); 1182 // uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 1183 // if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL)) 1184 // { 1185 // member_offset = memberOffset.ResolveValue(NULL, NULL).UInt(); 1186 // } 1187 // } 1188 break; 1189 1190 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break; 1191 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break; 1192 case DW_AT_declaration: 1193 case DW_AT_description: 1194 case DW_AT_mutable: 1195 case DW_AT_visibility: 1196 default: 1197 case DW_AT_sibling: 1198 break; 1199 } 1200 } 1201 } 1202 1203 // FIXME: Make Clang ignore Objective-C accessibility for expressions 1204 1205 if (class_language == eLanguageTypeObjC || 1206 class_language == eLanguageTypeObjC_plus_plus) 1207 accessibility = eAccessNone; 1208 1209 if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name)) 1210 { 1211 // Not all compilers will mark the vtable pointer 1212 // member as artificial (llvm-gcc). We can't have 1213 // the virtual members in our classes otherwise it 1214 // throws off all child offsets since we end up 1215 // having and extra pointer sized member in our 1216 // class layouts. 1217 is_artificial = true; 1218 } 1219 1220 if (is_artificial == false) 1221 { 1222 Type *member_type = ResolveTypeUID(encoding_uid); 1223 if (member_type) 1224 { 1225 if (accessibility == eAccessNone) 1226 accessibility = default_accessibility; 1227 member_accessibilities.push_back(accessibility); 1228 1229 GetClangASTContext().AddFieldToRecordType (class_clang_type, 1230 name, 1231 member_type->GetClangLayoutType(), 1232 accessibility, 1233 bit_size); 1234 } 1235 else 1236 { 1237 if (name) 1238 ReportError ("0x%8.8x: DW_TAG_member '%s' refers to type 0x%8.8x which was unable to be parsed", 1239 die->GetOffset(), 1240 name, 1241 encoding_uid); 1242 else 1243 ReportError ("0x%8.8x: DW_TAG_member refers to type 0x%8.8x which was unable to be parsed", 1244 die->GetOffset(), 1245 encoding_uid); 1246 } 1247 } 1248 } 1249 ++member_idx; 1250 } 1251 break; 1252 1253 case DW_TAG_subprogram: 1254 // Let the type parsing code handle this one for us. 1255 member_function_dies.Append (die); 1256 break; 1257 1258 case DW_TAG_inheritance: 1259 { 1260 is_a_class = true; 1261 if (default_accessibility == eAccessNone) 1262 default_accessibility = eAccessPrivate; 1263 // TODO: implement DW_TAG_inheritance type parsing 1264 DWARFDebugInfoEntry::Attributes attributes; 1265 const size_t num_attributes = die->GetAttributes (this, 1266 dwarf_cu, 1267 fixed_form_sizes, 1268 attributes); 1269 if (num_attributes > 0) 1270 { 1271 Declaration decl; 1272 DWARFExpression location; 1273 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 1274 AccessType accessibility = default_accessibility; 1275 bool is_virtual = false; 1276 bool is_base_of_class = true; 1277 off_t member_offset = 0; 1278 uint32_t i; 1279 for (i=0; i<num_attributes; ++i) 1280 { 1281 const dw_attr_t attr = attributes.AttributeAtIndex(i); 1282 DWARFFormValue form_value; 1283 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 1284 { 1285 switch (attr) 1286 { 1287 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 1288 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 1289 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 1290 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 1291 case DW_AT_data_member_location: 1292 if (form_value.BlockData()) 1293 { 1294 Value initialValue(0); 1295 Value memberOffset(0); 1296 const DataExtractor& debug_info_data = get_debug_info_data(); 1297 uint32_t block_length = form_value.Unsigned(); 1298 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 1299 if (DWARFExpression::Evaluate (NULL, 1300 NULL, 1301 NULL, 1302 NULL, 1303 NULL, 1304 debug_info_data, 1305 block_offset, 1306 block_length, 1307 eRegisterKindDWARF, 1308 &initialValue, 1309 memberOffset, 1310 NULL)) 1311 { 1312 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt(); 1313 } 1314 } 1315 break; 1316 1317 case DW_AT_accessibility: 1318 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); 1319 break; 1320 1321 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break; 1322 default: 1323 case DW_AT_sibling: 1324 break; 1325 } 1326 } 1327 } 1328 1329 Type *base_class_type = ResolveTypeUID(encoding_uid); 1330 assert(base_class_type); 1331 1332 clang_type_t base_class_clang_type = base_class_type->GetClangFullType(); 1333 assert (base_class_clang_type); 1334 if (class_language == eLanguageTypeObjC) 1335 { 1336 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type); 1337 } 1338 else 1339 { 1340 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type, 1341 accessibility, 1342 is_virtual, 1343 is_base_of_class)); 1344 } 1345 } 1346 } 1347 break; 1348 1349 default: 1350 break; 1351 } 1352 } 1353 return count; 1354 } 1355 1356 1357 clang::DeclContext* 1358 SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid) 1359 { 1360 DWARFDebugInfo* debug_info = DebugInfo(); 1361 if (debug_info) 1362 { 1363 DWARFCompileUnitSP cu_sp; 1364 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp); 1365 if (die) 1366 return GetClangDeclContextContainingDIE (cu_sp.get(), die); 1367 } 1368 return NULL; 1369 } 1370 1371 clang::DeclContext* 1372 SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid) 1373 { 1374 DWARFDebugInfo* debug_info = DebugInfo(); 1375 if (debug_info) 1376 { 1377 DWARFCompileUnitSP cu_sp; 1378 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp); 1379 if (die) 1380 return GetClangDeclContextForDIE (sc, cu_sp.get(), die); 1381 } 1382 return NULL; 1383 } 1384 1385 Type* 1386 SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid) 1387 { 1388 DWARFDebugInfo* debug_info = DebugInfo(); 1389 if (debug_info) 1390 { 1391 DWARFCompileUnitSP cu_sp; 1392 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp); 1393 if (type_die != NULL) 1394 { 1395 // We might be coming in in the middle of a type tree (a class 1396 // withing a class, an enum within a class), so parse any needed 1397 // parent DIEs before we get to this one... 1398 const DWARFDebugInfoEntry* parent_die = type_die->GetParent(); 1399 switch (parent_die->Tag()) 1400 { 1401 case DW_TAG_structure_type: 1402 case DW_TAG_union_type: 1403 case DW_TAG_class_type: 1404 ResolveType(cu_sp.get(), parent_die); 1405 break; 1406 } 1407 return ResolveType (cu_sp.get(), type_die); 1408 } 1409 } 1410 return NULL; 1411 } 1412 1413 // This function is used when SymbolFileDWARFDebugMap owns a bunch of 1414 // SymbolFileDWARF objects to detect if this DWARF file is the one that 1415 // can resolve a clang_type. 1416 bool 1417 SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type) 1418 { 1419 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type); 1420 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers); 1421 return die != NULL; 1422 } 1423 1424 1425 lldb::clang_type_t 1426 SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type) 1427 { 1428 // We have a struct/union/class/enum that needs to be fully resolved. 1429 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type); 1430 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers); 1431 if (die == NULL) 1432 { 1433 // if (m_debug_map_symfile) 1434 // { 1435 // Type *type = m_die_to_type[die]; 1436 // if (type && type->GetSymbolFile() != this) 1437 // return type->GetClangType(); 1438 // } 1439 // We have already resolved this type... 1440 return clang_type; 1441 } 1442 // Once we start resolving this type, remove it from the forward declaration 1443 // map in case anyone child members or other types require this type to get resolved. 1444 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition 1445 // are done. 1446 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers); 1447 1448 1449 DWARFDebugInfo* debug_info = DebugInfo(); 1450 1451 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get(); 1452 Type *type = m_die_to_type.lookup (die); 1453 1454 const dw_tag_t tag = die->Tag(); 1455 1456 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n", 1457 die->GetOffset(), 1458 DW_TAG_value_to_name(tag), 1459 type->GetName().AsCString()); 1460 assert (clang_type); 1461 DWARFDebugInfoEntry::Attributes attributes; 1462 1463 ClangASTContext &ast = GetClangASTContext(); 1464 1465 switch (tag) 1466 { 1467 case DW_TAG_structure_type: 1468 case DW_TAG_union_type: 1469 case DW_TAG_class_type: 1470 ast.StartTagDeclarationDefinition (clang_type); 1471 if (die->HasChildren()) 1472 { 1473 LanguageType class_language = eLanguageTypeUnknown; 1474 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type); 1475 if (is_objc_class) 1476 class_language = eLanguageTypeObjC; 1477 1478 int tag_decl_kind = -1; 1479 AccessType default_accessibility = eAccessNone; 1480 if (tag == DW_TAG_structure_type) 1481 { 1482 tag_decl_kind = clang::TTK_Struct; 1483 default_accessibility = eAccessPublic; 1484 } 1485 else if (tag == DW_TAG_union_type) 1486 { 1487 tag_decl_kind = clang::TTK_Union; 1488 default_accessibility = eAccessPublic; 1489 } 1490 else if (tag == DW_TAG_class_type) 1491 { 1492 tag_decl_kind = clang::TTK_Class; 1493 default_accessibility = eAccessPrivate; 1494 } 1495 1496 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu)); 1497 std::vector<clang::CXXBaseSpecifier *> base_classes; 1498 std::vector<int> member_accessibilities; 1499 bool is_a_class = false; 1500 // Parse members and base classes first 1501 DWARFDIECollection member_function_dies; 1502 1503 ParseChildMembers (sc, 1504 curr_cu, 1505 die, 1506 clang_type, 1507 class_language, 1508 base_classes, 1509 member_accessibilities, 1510 member_function_dies, 1511 default_accessibility, 1512 is_a_class); 1513 1514 // Now parse any methods if there were any... 1515 size_t num_functions = member_function_dies.Size(); 1516 if (num_functions > 0) 1517 { 1518 for (size_t i=0; i<num_functions; ++i) 1519 { 1520 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i)); 1521 } 1522 } 1523 1524 if (class_language == eLanguageTypeObjC) 1525 { 1526 std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type)); 1527 if (!class_str.empty()) 1528 { 1529 1530 ConstString class_name (class_str.c_str()); 1531 std::vector<NameToDIE::Info> method_die_infos; 1532 if (m_objc_class_selectors_index.Find (class_name, method_die_infos)) 1533 { 1534 DWARFCompileUnit* method_cu = NULL; 1535 DWARFCompileUnit* prev_method_cu = NULL; 1536 const size_t num_objc_methods = method_die_infos.size(); 1537 for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu) 1538 { 1539 method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx); 1540 1541 if (method_cu != prev_method_cu) 1542 method_cu->ExtractDIEsIfNeeded (false); 1543 1544 DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx); 1545 1546 ResolveType (method_cu, method_die); 1547 } 1548 } 1549 } 1550 } 1551 1552 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we 1553 // need to tell the clang type it is actually a class. 1554 if (class_language != eLanguageTypeObjC) 1555 { 1556 if (is_a_class && tag_decl_kind != clang::TTK_Class) 1557 ast.SetTagTypeKind (clang_type, clang::TTK_Class); 1558 } 1559 1560 // Since DW_TAG_structure_type gets used for both classes 1561 // and structures, we may need to set any DW_TAG_member 1562 // fields to have a "private" access if none was specified. 1563 // When we parsed the child members we tracked that actual 1564 // accessibility value for each DW_TAG_member in the 1565 // "member_accessibilities" array. If the value for the 1566 // member is zero, then it was set to the "default_accessibility" 1567 // which for structs was "public". Below we correct this 1568 // by setting any fields to "private" that weren't correctly 1569 // set. 1570 if (is_a_class && !member_accessibilities.empty()) 1571 { 1572 // This is a class and all members that didn't have 1573 // their access specified are private. 1574 ast.SetDefaultAccessForRecordFields (clang_type, 1575 eAccessPrivate, 1576 &member_accessibilities.front(), 1577 member_accessibilities.size()); 1578 } 1579 1580 if (!base_classes.empty()) 1581 { 1582 ast.SetBaseClassesForClassType (clang_type, 1583 &base_classes.front(), 1584 base_classes.size()); 1585 1586 // Clang will copy each CXXBaseSpecifier in "base_classes" 1587 // so we have to free them all. 1588 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(), 1589 base_classes.size()); 1590 } 1591 1592 } 1593 ast.CompleteTagDeclarationDefinition (clang_type); 1594 return clang_type; 1595 1596 case DW_TAG_enumeration_type: 1597 ast.StartTagDeclarationDefinition (clang_type); 1598 if (die->HasChildren()) 1599 { 1600 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu)); 1601 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die); 1602 } 1603 ast.CompleteTagDeclarationDefinition (clang_type); 1604 return clang_type; 1605 1606 default: 1607 assert(false && "not a forward clang type decl!"); 1608 break; 1609 } 1610 return NULL; 1611 } 1612 1613 Type* 1614 SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed) 1615 { 1616 if (type_die != NULL) 1617 { 1618 Type *type = m_die_to_type.lookup (type_die); 1619 if (type == NULL) 1620 type = GetTypeForDIE (curr_cu, type_die).get(); 1621 if (assert_not_being_parsed) 1622 assert (type != DIE_IS_BEING_PARSED); 1623 return type; 1624 } 1625 return NULL; 1626 } 1627 1628 CompileUnit* 1629 SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx) 1630 { 1631 // Check if the symbol vendor already knows about this compile unit? 1632 if (curr_cu->GetUserData() == NULL) 1633 { 1634 // The symbol vendor doesn't know about this compile unit, we 1635 // need to parse and add it to the symbol vendor object. 1636 CompUnitSP dc_cu; 1637 ParseCompileUnit(curr_cu, dc_cu); 1638 if (dc_cu.get()) 1639 { 1640 // Figure out the compile unit index if we weren't given one 1641 if (cu_idx == UINT32_MAX) 1642 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx); 1643 1644 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx); 1645 1646 if (m_debug_map_symfile) 1647 m_debug_map_symfile->SetCompileUnit(this, dc_cu); 1648 } 1649 } 1650 return (CompileUnit*)curr_cu->GetUserData(); 1651 } 1652 1653 bool 1654 SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc) 1655 { 1656 sc.Clear(); 1657 // Check if the symbol vendor already knows about this compile unit? 1658 sc.module_sp = m_obj_file->GetModule()->GetSP(); 1659 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX); 1660 1661 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get(); 1662 if (sc.function == NULL) 1663 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die); 1664 1665 return sc.function != NULL; 1666 } 1667 1668 uint32_t 1669 SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 1670 { 1671 Timer scoped_timer(__PRETTY_FUNCTION__, 1672 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)", 1673 so_addr.GetSection(), 1674 so_addr.GetOffset(), 1675 resolve_scope); 1676 uint32_t resolved = 0; 1677 if (resolve_scope & ( eSymbolContextCompUnit | 1678 eSymbolContextFunction | 1679 eSymbolContextBlock | 1680 eSymbolContextLineEntry)) 1681 { 1682 lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); 1683 1684 DWARFDebugAranges* debug_aranges = DebugAranges(); 1685 DWARFDebugInfo* debug_info = DebugInfo(); 1686 if (debug_aranges) 1687 { 1688 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr); 1689 if (cu_offset != DW_INVALID_OFFSET) 1690 { 1691 uint32_t cu_idx; 1692 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get(); 1693 if (curr_cu) 1694 { 1695 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx); 1696 assert(sc.comp_unit != NULL); 1697 resolved |= eSymbolContextCompUnit; 1698 1699 if (resolve_scope & eSymbolContextLineEntry) 1700 { 1701 LineTable *line_table = sc.comp_unit->GetLineTable(); 1702 if (line_table == NULL) 1703 { 1704 if (ParseCompileUnitLineTable(sc)) 1705 line_table = sc.comp_unit->GetLineTable(); 1706 } 1707 if (line_table != NULL) 1708 { 1709 if (so_addr.IsLinkedAddress()) 1710 { 1711 Address linked_addr (so_addr); 1712 linked_addr.ResolveLinkedAddress(); 1713 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry)) 1714 { 1715 resolved |= eSymbolContextLineEntry; 1716 } 1717 } 1718 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry)) 1719 { 1720 resolved |= eSymbolContextLineEntry; 1721 } 1722 } 1723 } 1724 1725 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 1726 { 1727 DWARFDebugInfoEntry *function_die = NULL; 1728 DWARFDebugInfoEntry *block_die = NULL; 1729 if (resolve_scope & eSymbolContextBlock) 1730 { 1731 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die); 1732 } 1733 else 1734 { 1735 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL); 1736 } 1737 1738 if (function_die != NULL) 1739 { 1740 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get(); 1741 if (sc.function == NULL) 1742 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die); 1743 } 1744 1745 if (sc.function != NULL) 1746 { 1747 resolved |= eSymbolContextFunction; 1748 1749 if (resolve_scope & eSymbolContextBlock) 1750 { 1751 Block& block = sc.function->GetBlock (true); 1752 1753 if (block_die != NULL) 1754 sc.block = block.FindBlockByID (block_die->GetOffset()); 1755 else 1756 sc.block = block.FindBlockByID (function_die->GetOffset()); 1757 if (sc.block) 1758 resolved |= eSymbolContextBlock; 1759 } 1760 } 1761 } 1762 } 1763 } 1764 } 1765 } 1766 return resolved; 1767 } 1768 1769 1770 1771 uint32_t 1772 SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 1773 { 1774 const uint32_t prev_size = sc_list.GetSize(); 1775 if (resolve_scope & eSymbolContextCompUnit) 1776 { 1777 DWARFDebugInfo* debug_info = DebugInfo(); 1778 if (debug_info) 1779 { 1780 uint32_t cu_idx; 1781 DWARFCompileUnit* curr_cu = NULL; 1782 1783 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx) 1784 { 1785 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx); 1786 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0; 1787 if (check_inlines || file_spec_matches_cu_file_spec) 1788 { 1789 SymbolContext sc (m_obj_file->GetModule()); 1790 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx); 1791 assert(sc.comp_unit != NULL); 1792 1793 uint32_t file_idx = UINT32_MAX; 1794 1795 // If we are looking for inline functions only and we don't 1796 // find it in the support files, we are done. 1797 if (check_inlines) 1798 { 1799 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec); 1800 if (file_idx == UINT32_MAX) 1801 continue; 1802 } 1803 1804 if (line != 0) 1805 { 1806 LineTable *line_table = sc.comp_unit->GetLineTable(); 1807 1808 if (line_table != NULL && line != 0) 1809 { 1810 // We will have already looked up the file index if 1811 // we are searching for inline entries. 1812 if (!check_inlines) 1813 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec); 1814 1815 if (file_idx != UINT32_MAX) 1816 { 1817 uint32_t found_line; 1818 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry); 1819 found_line = sc.line_entry.line; 1820 1821 while (line_idx != UINT32_MAX) 1822 { 1823 sc.function = NULL; 1824 sc.block = NULL; 1825 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 1826 { 1827 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress(); 1828 if (file_vm_addr != LLDB_INVALID_ADDRESS) 1829 { 1830 DWARFDebugInfoEntry *function_die = NULL; 1831 DWARFDebugInfoEntry *block_die = NULL; 1832 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL); 1833 1834 if (function_die != NULL) 1835 { 1836 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get(); 1837 if (sc.function == NULL) 1838 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die); 1839 } 1840 1841 if (sc.function != NULL) 1842 { 1843 Block& block = sc.function->GetBlock (true); 1844 1845 if (block_die != NULL) 1846 sc.block = block.FindBlockByID (block_die->GetOffset()); 1847 else 1848 sc.block = block.FindBlockByID (function_die->GetOffset()); 1849 } 1850 } 1851 } 1852 1853 sc_list.Append(sc); 1854 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry); 1855 } 1856 } 1857 } 1858 else if (file_spec_matches_cu_file_spec && !check_inlines) 1859 { 1860 // only append the context if we aren't looking for inline call sites 1861 // by file and line and if the file spec matches that of the compile unit 1862 sc_list.Append(sc); 1863 } 1864 } 1865 else if (file_spec_matches_cu_file_spec && !check_inlines) 1866 { 1867 // only append the context if we aren't looking for inline call sites 1868 // by file and line and if the file spec matches that of the compile unit 1869 sc_list.Append(sc); 1870 } 1871 1872 if (!check_inlines) 1873 break; 1874 } 1875 } 1876 } 1877 } 1878 return sc_list.GetSize() - prev_size; 1879 } 1880 1881 void 1882 SymbolFileDWARF::Index () 1883 { 1884 if (m_indexed) 1885 return; 1886 m_indexed = true; 1887 Timer scoped_timer (__PRETTY_FUNCTION__, 1888 "SymbolFileDWARF::Index (%s)", 1889 GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 1890 1891 DWARFDebugInfo* debug_info = DebugInfo(); 1892 if (debug_info) 1893 { 1894 m_aranges.reset(new DWARFDebugAranges()); 1895 1896 uint32_t cu_idx = 0; 1897 const uint32_t num_compile_units = GetNumCompileUnits(); 1898 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) 1899 { 1900 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx); 1901 1902 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1; 1903 1904 curr_cu->Index (cu_idx, 1905 m_function_basename_index, 1906 m_function_fullname_index, 1907 m_function_method_index, 1908 m_function_selector_index, 1909 m_objc_class_selectors_index, 1910 m_global_index, 1911 m_type_index, 1912 m_namespace_index, 1913 DebugRanges(), 1914 m_aranges.get()); 1915 1916 // Keep memory down by clearing DIEs if this generate function 1917 // caused them to be parsed 1918 if (clear_dies) 1919 curr_cu->ClearDIEs (true); 1920 } 1921 1922 m_aranges->Sort(); 1923 1924 #if defined (ENABLE_DEBUG_PRINTF) 1925 StreamFile s(stdout, false); 1926 s.Printf ("DWARF index for (%s) '%s/%s':", 1927 GetObjectFile()->GetModule()->GetArchitecture().AsCString(), 1928 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(), 1929 GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 1930 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s); 1931 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s); 1932 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s); 1933 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s); 1934 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s); 1935 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s); 1936 s.Printf("\nTypes:\n"); m_type_index.Dump (&s); 1937 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s); 1938 #endif 1939 } 1940 } 1941 1942 uint32_t 1943 SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables) 1944 { 1945 DWARFDebugInfo* info = DebugInfo(); 1946 if (info == NULL) 1947 return 0; 1948 1949 // If we aren't appending the results to this list, then clear the list 1950 if (!append) 1951 variables.Clear(); 1952 1953 // Remember how many variables are in the list before we search in case 1954 // we are appending the results to a variable list. 1955 const uint32_t original_size = variables.GetSize(); 1956 1957 // Index the DWARF if we haven't already 1958 if (!m_indexed) 1959 Index (); 1960 1961 SymbolContext sc; 1962 sc.module_sp = m_obj_file->GetModule()->GetSP(); 1963 assert (sc.module_sp); 1964 1965 DWARFCompileUnit* curr_cu = NULL; 1966 DWARFCompileUnit* prev_cu = NULL; 1967 const DWARFDebugInfoEntry* die = NULL; 1968 std::vector<NameToDIE::Info> die_info_array; 1969 const size_t num_matches = m_global_index.Find(name, die_info_array); 1970 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) 1971 { 1972 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); 1973 1974 if (curr_cu != prev_cu) 1975 curr_cu->ExtractDIEsIfNeeded (false); 1976 1977 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); 1978 1979 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX); 1980 assert(sc.comp_unit != NULL); 1981 1982 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables); 1983 1984 if (variables.GetSize() - original_size >= max_matches) 1985 break; 1986 } 1987 1988 // Return the number of variable that were appended to the list 1989 return variables.GetSize() - original_size; 1990 } 1991 1992 uint32_t 1993 SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 1994 { 1995 DWARFDebugInfo* info = DebugInfo(); 1996 if (info == NULL) 1997 return 0; 1998 1999 // If we aren't appending the results to this list, then clear the list 2000 if (!append) 2001 variables.Clear(); 2002 2003 // Remember how many variables are in the list before we search in case 2004 // we are appending the results to a variable list. 2005 const uint32_t original_size = variables.GetSize(); 2006 2007 // Index the DWARF if we haven't already 2008 if (!m_indexed) 2009 Index (); 2010 2011 SymbolContext sc; 2012 sc.module_sp = m_obj_file->GetModule()->GetSP(); 2013 assert (sc.module_sp); 2014 2015 DWARFCompileUnit* curr_cu = NULL; 2016 DWARFCompileUnit* prev_cu = NULL; 2017 const DWARFDebugInfoEntry* die = NULL; 2018 std::vector<NameToDIE::Info> die_info_array; 2019 const size_t num_matches = m_global_index.Find(regex, die_info_array); 2020 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) 2021 { 2022 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); 2023 2024 if (curr_cu != prev_cu) 2025 curr_cu->ExtractDIEsIfNeeded (false); 2026 2027 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); 2028 2029 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX); 2030 assert(sc.comp_unit != NULL); 2031 2032 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables); 2033 2034 if (variables.GetSize() - original_size >= max_matches) 2035 break; 2036 } 2037 2038 // Return the number of variable that were appended to the list 2039 return variables.GetSize() - original_size; 2040 } 2041 2042 2043 void 2044 SymbolFileDWARF::FindFunctions 2045 ( 2046 const ConstString &name, 2047 const NameToDIE &name_to_die, 2048 SymbolContextList& sc_list 2049 ) 2050 { 2051 DWARFDebugInfo* info = DebugInfo(); 2052 if (info == NULL) 2053 return; 2054 2055 SymbolContext sc; 2056 sc.module_sp = m_obj_file->GetModule()->GetSP(); 2057 assert (sc.module_sp); 2058 2059 DWARFCompileUnit* curr_cu = NULL; 2060 DWARFCompileUnit* prev_cu = NULL; 2061 const DWARFDebugInfoEntry* die = NULL; 2062 std::vector<NameToDIE::Info> die_info_array; 2063 const size_t num_matches = name_to_die.Find (name, die_info_array); 2064 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) 2065 { 2066 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); 2067 2068 if (curr_cu != prev_cu) 2069 curr_cu->ExtractDIEsIfNeeded (false); 2070 2071 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); 2072 2073 const DWARFDebugInfoEntry* inlined_die = NULL; 2074 if (die->Tag() == DW_TAG_inlined_subroutine) 2075 { 2076 inlined_die = die; 2077 2078 while ((die = die->GetParent()) != NULL) 2079 { 2080 if (die->Tag() == DW_TAG_subprogram) 2081 break; 2082 } 2083 } 2084 assert (die->Tag() == DW_TAG_subprogram); 2085 if (GetFunction (curr_cu, die, sc)) 2086 { 2087 Address addr; 2088 // Parse all blocks if needed 2089 if (inlined_die) 2090 { 2091 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset()); 2092 assert (sc.block != NULL); 2093 if (sc.block->GetStartAddress (addr) == false) 2094 addr.Clear(); 2095 } 2096 else 2097 { 2098 sc.block = NULL; 2099 addr = sc.function->GetAddressRange().GetBaseAddress(); 2100 } 2101 2102 if (addr.IsValid()) 2103 { 2104 2105 // We found the function, so we should find the line table 2106 // and line table entry as well 2107 LineTable *line_table = sc.comp_unit->GetLineTable(); 2108 if (line_table == NULL) 2109 { 2110 if (ParseCompileUnitLineTable(sc)) 2111 line_table = sc.comp_unit->GetLineTable(); 2112 } 2113 if (line_table != NULL) 2114 line_table->FindLineEntryByAddress (addr, sc.line_entry); 2115 2116 sc_list.Append(sc); 2117 } 2118 } 2119 } 2120 } 2121 2122 2123 void 2124 SymbolFileDWARF::FindFunctions 2125 ( 2126 const RegularExpression ®ex, 2127 const NameToDIE &name_to_die, 2128 SymbolContextList& sc_list 2129 ) 2130 { 2131 DWARFDebugInfo* info = DebugInfo(); 2132 if (info == NULL) 2133 return; 2134 2135 SymbolContext sc; 2136 sc.module_sp = m_obj_file->GetModule()->GetSP(); 2137 assert (sc.module_sp); 2138 2139 DWARFCompileUnit* curr_cu = NULL; 2140 DWARFCompileUnit* prev_cu = NULL; 2141 const DWARFDebugInfoEntry* die = NULL; 2142 std::vector<NameToDIE::Info> die_info_array; 2143 const size_t num_matches = name_to_die.Find(regex, die_info_array); 2144 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) 2145 { 2146 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); 2147 2148 if (curr_cu != prev_cu) 2149 curr_cu->ExtractDIEsIfNeeded (false); 2150 2151 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); 2152 2153 const DWARFDebugInfoEntry* inlined_die = NULL; 2154 if (die->Tag() == DW_TAG_inlined_subroutine) 2155 { 2156 inlined_die = die; 2157 2158 while ((die = die->GetParent()) != NULL) 2159 { 2160 if (die->Tag() == DW_TAG_subprogram) 2161 break; 2162 } 2163 } 2164 assert (die->Tag() == DW_TAG_subprogram); 2165 if (GetFunction (curr_cu, die, sc)) 2166 { 2167 Address addr; 2168 // Parse all blocks if needed 2169 if (inlined_die) 2170 { 2171 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset()); 2172 assert (sc.block != NULL); 2173 if (sc.block->GetStartAddress (addr) == false) 2174 addr.Clear(); 2175 } 2176 else 2177 { 2178 sc.block = NULL; 2179 addr = sc.function->GetAddressRange().GetBaseAddress(); 2180 } 2181 2182 if (addr.IsValid()) 2183 { 2184 2185 // We found the function, so we should find the line table 2186 // and line table entry as well 2187 LineTable *line_table = sc.comp_unit->GetLineTable(); 2188 if (line_table == NULL) 2189 { 2190 if (ParseCompileUnitLineTable(sc)) 2191 line_table = sc.comp_unit->GetLineTable(); 2192 } 2193 if (line_table != NULL) 2194 line_table->FindLineEntryByAddress (addr, sc.line_entry); 2195 2196 sc_list.Append(sc); 2197 } 2198 } 2199 } 2200 } 2201 2202 uint32_t 2203 SymbolFileDWARF::FindFunctions 2204 ( 2205 const ConstString &name, 2206 uint32_t name_type_mask, 2207 bool append, 2208 SymbolContextList& sc_list 2209 ) 2210 { 2211 Timer scoped_timer (__PRETTY_FUNCTION__, 2212 "SymbolFileDWARF::FindFunctions (name = '%s')", 2213 name.AsCString()); 2214 2215 // If we aren't appending the results to this list, then clear the list 2216 if (!append) 2217 sc_list.Clear(); 2218 2219 // Remember how many sc_list are in the list before we search in case 2220 // we are appending the results to a variable list. 2221 uint32_t original_size = sc_list.GetSize(); 2222 2223 // Index the DWARF if we haven't already 2224 if (!m_indexed) 2225 Index (); 2226 2227 if (name_type_mask & eFunctionNameTypeBase) 2228 FindFunctions (name, m_function_basename_index, sc_list); 2229 2230 if (name_type_mask & eFunctionNameTypeFull) 2231 FindFunctions (name, m_function_fullname_index, sc_list); 2232 2233 if (name_type_mask & eFunctionNameTypeMethod) 2234 FindFunctions (name, m_function_method_index, sc_list); 2235 2236 if (name_type_mask & eFunctionNameTypeSelector) 2237 FindFunctions (name, m_function_selector_index, sc_list); 2238 2239 // Return the number of variable that were appended to the list 2240 return sc_list.GetSize() - original_size; 2241 } 2242 2243 2244 uint32_t 2245 SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list) 2246 { 2247 Timer scoped_timer (__PRETTY_FUNCTION__, 2248 "SymbolFileDWARF::FindFunctions (regex = '%s')", 2249 regex.GetText()); 2250 2251 // If we aren't appending the results to this list, then clear the list 2252 if (!append) 2253 sc_list.Clear(); 2254 2255 // Remember how many sc_list are in the list before we search in case 2256 // we are appending the results to a variable list. 2257 uint32_t original_size = sc_list.GetSize(); 2258 2259 // Index the DWARF if we haven't already 2260 if (!m_indexed) 2261 Index (); 2262 2263 FindFunctions (regex, m_function_basename_index, sc_list); 2264 2265 FindFunctions (regex, m_function_fullname_index, sc_list); 2266 2267 // Return the number of variable that were appended to the list 2268 return sc_list.GetSize() - original_size; 2269 } 2270 void 2271 SymbolFileDWARF::ReportError (const char *format, ...) 2272 { 2273 ::fprintf (stderr, 2274 "error: %s/%s ", 2275 m_obj_file->GetFileSpec().GetDirectory().GetCString(), 2276 m_obj_file->GetFileSpec().GetFilename().GetCString()); 2277 2278 va_list args; 2279 va_start (args, format); 2280 vfprintf (stderr, format, args); 2281 va_end (args); 2282 } 2283 2284 uint32_t 2285 SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types) 2286 { 2287 DWARFDebugInfo* info = DebugInfo(); 2288 if (info == NULL) 2289 return 0; 2290 2291 // If we aren't appending the results to this list, then clear the list 2292 if (!append) 2293 types.Clear(); 2294 2295 // Index if we already haven't to make sure the compile units 2296 // get indexed and make their global DIE index list 2297 if (!m_indexed) 2298 Index (); 2299 2300 const uint32_t initial_types_size = types.GetSize(); 2301 DWARFCompileUnit* curr_cu = NULL; 2302 DWARFCompileUnit* prev_cu = NULL; 2303 const DWARFDebugInfoEntry* die = NULL; 2304 std::vector<NameToDIE::Info> die_info_array; 2305 const size_t num_matches = m_type_index.Find (name, die_info_array); 2306 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) 2307 { 2308 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); 2309 2310 if (curr_cu != prev_cu) 2311 curr_cu->ExtractDIEsIfNeeded (false); 2312 2313 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); 2314 2315 Type *matching_type = ResolveType (curr_cu, die); 2316 if (matching_type) 2317 { 2318 // We found a type pointer, now find the shared pointer form our type list 2319 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID())); 2320 if (type_sp) 2321 { 2322 types.InsertUnique (type_sp); 2323 if (types.GetSize() >= max_matches) 2324 break; 2325 } 2326 else 2327 { 2328 fprintf (stderr, "error: can't find shared pointer for type 0x%8.8x.\n", matching_type->GetID()); 2329 } 2330 } 2331 } 2332 return types.GetSize() - initial_types_size; 2333 } 2334 2335 2336 ClangNamespaceDecl 2337 SymbolFileDWARF::FindNamespace (const SymbolContext& sc, 2338 const ConstString &name) 2339 { 2340 ClangNamespaceDecl namespace_decl; 2341 DWARFDebugInfo* info = DebugInfo(); 2342 if (info) 2343 { 2344 // Index if we already haven't to make sure the compile units 2345 // get indexed and make their global DIE index list 2346 if (!m_indexed) 2347 Index (); 2348 2349 DWARFCompileUnit* curr_cu = NULL; 2350 DWARFCompileUnit* prev_cu = NULL; 2351 const DWARFDebugInfoEntry* die = NULL; 2352 std::vector<NameToDIE::Info> die_info_array; 2353 const size_t num_matches = m_namespace_index.Find (name, die_info_array); 2354 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) 2355 { 2356 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); 2357 2358 if (curr_cu != prev_cu) 2359 curr_cu->ExtractDIEsIfNeeded (false); 2360 2361 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); 2362 2363 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (curr_cu, die); 2364 if (clang_namespace_decl) 2365 { 2366 namespace_decl.SetASTContext (GetClangASTContext().getASTContext()); 2367 namespace_decl.SetNamespaceDecl (clang_namespace_decl); 2368 } 2369 } 2370 } 2371 return namespace_decl; 2372 } 2373 2374 uint32_t 2375 SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types) 2376 { 2377 // Remember how many sc_list are in the list before we search in case 2378 // we are appending the results to a variable list. 2379 uint32_t original_size = types.GetSize(); 2380 2381 const uint32_t num_die_offsets = die_offsets.size(); 2382 // Parse all of the types we found from the pubtypes matches 2383 uint32_t i; 2384 uint32_t num_matches = 0; 2385 for (i = 0; i < num_die_offsets; ++i) 2386 { 2387 Type *matching_type = ResolveTypeUID (die_offsets[i]); 2388 if (matching_type) 2389 { 2390 // We found a type pointer, now find the shared pointer form our type list 2391 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID())); 2392 assert (type_sp.get() != NULL); 2393 types.InsertUnique (type_sp); 2394 ++num_matches; 2395 if (num_matches >= max_matches) 2396 break; 2397 } 2398 } 2399 2400 // Return the number of variable that were appended to the list 2401 return types.GetSize() - original_size; 2402 } 2403 2404 2405 size_t 2406 SymbolFileDWARF::ParseChildParameters 2407 ( 2408 const SymbolContext& sc, 2409 TypeSP& type_sp, 2410 DWARFCompileUnit* dwarf_cu, 2411 const DWARFDebugInfoEntry *parent_die, 2412 bool skip_artificial, 2413 bool &is_static, 2414 TypeList* type_list, 2415 std::vector<clang_type_t>& function_param_types, 2416 std::vector<clang::ParmVarDecl*>& function_param_decls, 2417 unsigned &type_quals 2418 ) 2419 { 2420 if (parent_die == NULL) 2421 return 0; 2422 2423 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 2424 2425 size_t arg_idx = 0; 2426 const DWARFDebugInfoEntry *die; 2427 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2428 { 2429 dw_tag_t tag = die->Tag(); 2430 switch (tag) 2431 { 2432 case DW_TAG_formal_parameter: 2433 { 2434 DWARFDebugInfoEntry::Attributes attributes; 2435 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 2436 if (num_attributes > 0) 2437 { 2438 const char *name = NULL; 2439 Declaration decl; 2440 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET; 2441 bool is_artificial = false; 2442 // one of None, Auto, Register, Extern, Static, PrivateExtern 2443 2444 clang::StorageClass storage = clang::SC_None; 2445 uint32_t i; 2446 for (i=0; i<num_attributes; ++i) 2447 { 2448 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2449 DWARFFormValue form_value; 2450 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2451 { 2452 switch (attr) 2453 { 2454 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2455 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2456 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2457 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 2458 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break; 2459 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break; 2460 case DW_AT_location: 2461 // if (form_value.BlockData()) 2462 // { 2463 // const DataExtractor& debug_info_data = debug_info(); 2464 // uint32_t block_length = form_value.Unsigned(); 2465 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length); 2466 // } 2467 // else 2468 // { 2469 // } 2470 // break; 2471 case DW_AT_const_value: 2472 case DW_AT_default_value: 2473 case DW_AT_description: 2474 case DW_AT_endianity: 2475 case DW_AT_is_optional: 2476 case DW_AT_segment: 2477 case DW_AT_variable_parameter: 2478 default: 2479 case DW_AT_abstract_origin: 2480 case DW_AT_sibling: 2481 break; 2482 } 2483 } 2484 } 2485 2486 bool skip = false; 2487 if (skip_artificial) 2488 { 2489 if (is_artificial) 2490 { 2491 // In order to determine if a C++ member function is 2492 // "const" we have to look at the const-ness of "this"... 2493 // Ugly, but that 2494 if (arg_idx == 0) 2495 { 2496 const DWARFDebugInfoEntry *grandparent_die = parent_die->GetParent(); 2497 if (grandparent_die && (grandparent_die->Tag() == DW_TAG_structure_type || 2498 grandparent_die->Tag() == DW_TAG_class_type)) 2499 { 2500 LanguageType language = sc.comp_unit->GetLanguage(); 2501 if (language == eLanguageTypeObjC_plus_plus || language == eLanguageTypeC_plus_plus) 2502 { 2503 // Often times compilers omit the "this" name for the 2504 // specification DIEs, so we can't rely upon the name 2505 // being in the formal parameter DIE... 2506 if (name == NULL || ::strcmp(name, "this")==0) 2507 { 2508 Type *this_type = ResolveTypeUID (param_type_die_offset); 2509 if (this_type) 2510 { 2511 uint32_t encoding_mask = this_type->GetEncodingMask(); 2512 if (encoding_mask & Type::eEncodingIsPointerUID) 2513 { 2514 is_static = false; 2515 2516 if (encoding_mask & (1u << Type::eEncodingIsConstUID)) 2517 type_quals |= clang::Qualifiers::Const; 2518 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID)) 2519 type_quals |= clang::Qualifiers::Volatile; 2520 } 2521 } 2522 } 2523 } 2524 } 2525 } 2526 skip = true; 2527 } 2528 else 2529 { 2530 2531 // HACK: Objective C formal parameters "self" and "_cmd" 2532 // are not marked as artificial in the DWARF... 2533 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX); 2534 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus)) 2535 { 2536 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0)) 2537 skip = true; 2538 } 2539 } 2540 } 2541 2542 if (!skip) 2543 { 2544 Type *type = ResolveTypeUID(param_type_die_offset); 2545 if (type) 2546 { 2547 function_param_types.push_back (type->GetClangForwardType()); 2548 2549 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage); 2550 assert(param_var_decl); 2551 function_param_decls.push_back(param_var_decl); 2552 } 2553 } 2554 } 2555 arg_idx++; 2556 } 2557 break; 2558 2559 default: 2560 break; 2561 } 2562 } 2563 return arg_idx; 2564 } 2565 2566 size_t 2567 SymbolFileDWARF::ParseChildEnumerators 2568 ( 2569 const SymbolContext& sc, 2570 clang_type_t enumerator_clang_type, 2571 uint32_t enumerator_byte_size, 2572 DWARFCompileUnit* dwarf_cu, 2573 const DWARFDebugInfoEntry *parent_die 2574 ) 2575 { 2576 if (parent_die == NULL) 2577 return 0; 2578 2579 size_t enumerators_added = 0; 2580 const DWARFDebugInfoEntry *die; 2581 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 2582 2583 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2584 { 2585 const dw_tag_t tag = die->Tag(); 2586 if (tag == DW_TAG_enumerator) 2587 { 2588 DWARFDebugInfoEntry::Attributes attributes; 2589 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 2590 if (num_child_attributes > 0) 2591 { 2592 const char *name = NULL; 2593 bool got_value = false; 2594 int64_t enum_value = 0; 2595 Declaration decl; 2596 2597 uint32_t i; 2598 for (i=0; i<num_child_attributes; ++i) 2599 { 2600 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2601 DWARFFormValue form_value; 2602 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2603 { 2604 switch (attr) 2605 { 2606 case DW_AT_const_value: 2607 got_value = true; 2608 enum_value = form_value.Unsigned(); 2609 break; 2610 2611 case DW_AT_name: 2612 name = form_value.AsCString(&get_debug_str_data()); 2613 break; 2614 2615 case DW_AT_description: 2616 default: 2617 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2618 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2619 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2620 case DW_AT_sibling: 2621 break; 2622 } 2623 } 2624 } 2625 2626 if (name && name[0] && got_value) 2627 { 2628 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type, 2629 enumerator_clang_type, 2630 decl, 2631 name, 2632 enum_value, 2633 enumerator_byte_size * 8); 2634 ++enumerators_added; 2635 } 2636 } 2637 } 2638 } 2639 return enumerators_added; 2640 } 2641 2642 void 2643 SymbolFileDWARF::ParseChildArrayInfo 2644 ( 2645 const SymbolContext& sc, 2646 DWARFCompileUnit* dwarf_cu, 2647 const DWARFDebugInfoEntry *parent_die, 2648 int64_t& first_index, 2649 std::vector<uint64_t>& element_orders, 2650 uint32_t& byte_stride, 2651 uint32_t& bit_stride 2652 ) 2653 { 2654 if (parent_die == NULL) 2655 return; 2656 2657 const DWARFDebugInfoEntry *die; 2658 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 2659 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2660 { 2661 const dw_tag_t tag = die->Tag(); 2662 switch (tag) 2663 { 2664 case DW_TAG_enumerator: 2665 { 2666 DWARFDebugInfoEntry::Attributes attributes; 2667 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 2668 if (num_child_attributes > 0) 2669 { 2670 const char *name = NULL; 2671 bool got_value = false; 2672 int64_t enum_value = 0; 2673 2674 uint32_t i; 2675 for (i=0; i<num_child_attributes; ++i) 2676 { 2677 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2678 DWARFFormValue form_value; 2679 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2680 { 2681 switch (attr) 2682 { 2683 case DW_AT_const_value: 2684 got_value = true; 2685 enum_value = form_value.Unsigned(); 2686 break; 2687 2688 case DW_AT_name: 2689 name = form_value.AsCString(&get_debug_str_data()); 2690 break; 2691 2692 case DW_AT_description: 2693 default: 2694 case DW_AT_decl_file: 2695 case DW_AT_decl_line: 2696 case DW_AT_decl_column: 2697 case DW_AT_sibling: 2698 break; 2699 } 2700 } 2701 } 2702 } 2703 } 2704 break; 2705 2706 case DW_TAG_subrange_type: 2707 { 2708 DWARFDebugInfoEntry::Attributes attributes; 2709 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 2710 if (num_child_attributes > 0) 2711 { 2712 const char *name = NULL; 2713 bool got_value = false; 2714 uint64_t byte_size = 0; 2715 int64_t enum_value = 0; 2716 uint64_t num_elements = 0; 2717 uint64_t lower_bound = 0; 2718 uint64_t upper_bound = 0; 2719 uint32_t i; 2720 for (i=0; i<num_child_attributes; ++i) 2721 { 2722 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2723 DWARFFormValue form_value; 2724 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2725 { 2726 switch (attr) 2727 { 2728 case DW_AT_const_value: 2729 got_value = true; 2730 enum_value = form_value.Unsigned(); 2731 break; 2732 2733 case DW_AT_name: 2734 name = form_value.AsCString(&get_debug_str_data()); 2735 break; 2736 2737 case DW_AT_count: 2738 num_elements = form_value.Unsigned(); 2739 break; 2740 2741 case DW_AT_bit_stride: 2742 bit_stride = form_value.Unsigned(); 2743 break; 2744 2745 case DW_AT_byte_stride: 2746 byte_stride = form_value.Unsigned(); 2747 break; 2748 2749 case DW_AT_byte_size: 2750 byte_size = form_value.Unsigned(); 2751 break; 2752 2753 case DW_AT_lower_bound: 2754 lower_bound = form_value.Unsigned(); 2755 break; 2756 2757 case DW_AT_upper_bound: 2758 upper_bound = form_value.Unsigned(); 2759 break; 2760 2761 default: 2762 case DW_AT_abstract_origin: 2763 case DW_AT_accessibility: 2764 case DW_AT_allocated: 2765 case DW_AT_associated: 2766 case DW_AT_data_location: 2767 case DW_AT_declaration: 2768 case DW_AT_description: 2769 case DW_AT_sibling: 2770 case DW_AT_threads_scaled: 2771 case DW_AT_type: 2772 case DW_AT_visibility: 2773 break; 2774 } 2775 } 2776 } 2777 2778 if (upper_bound > lower_bound) 2779 num_elements = upper_bound - lower_bound + 1; 2780 2781 if (num_elements > 0) 2782 element_orders.push_back (num_elements); 2783 } 2784 } 2785 break; 2786 } 2787 } 2788 } 2789 2790 TypeSP 2791 SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die) 2792 { 2793 TypeSP type_sp; 2794 if (die != NULL) 2795 { 2796 assert(curr_cu != NULL); 2797 Type *type_ptr = m_die_to_type.lookup (die); 2798 if (type_ptr == NULL) 2799 { 2800 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu); 2801 assert (lldb_cu); 2802 SymbolContext sc(lldb_cu); 2803 type_sp = ParseType(sc, curr_cu, die, NULL); 2804 } 2805 else if (type_ptr != DIE_IS_BEING_PARSED) 2806 { 2807 // Grab the existing type from the master types lists 2808 type_sp = GetTypeList()->FindType(type_ptr->GetID()); 2809 } 2810 2811 } 2812 return type_sp; 2813 } 2814 2815 clang::DeclContext * 2816 SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset) 2817 { 2818 if (die_offset != DW_INVALID_OFFSET) 2819 { 2820 DWARFCompileUnitSP cu_sp; 2821 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp); 2822 return GetClangDeclContextContainingDIE (cu_sp.get(), die); 2823 } 2824 return NULL; 2825 } 2826 2827 clang::DeclContext * 2828 SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset) 2829 { 2830 if (die_offset != DW_INVALID_OFFSET) 2831 { 2832 DWARFCompileUnitSP cu_sp; 2833 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp); 2834 return GetClangDeclContextForDIE (sc, cu_sp.get(), die); 2835 } 2836 return NULL; 2837 } 2838 2839 clang::NamespaceDecl * 2840 SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die) 2841 { 2842 if (die->Tag() == DW_TAG_namespace) 2843 { 2844 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL); 2845 if (namespace_name) 2846 { 2847 Declaration decl; // TODO: fill in the decl object 2848 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (curr_cu, die->GetParent())); 2849 if (namespace_decl) 2850 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die); 2851 return namespace_decl; 2852 } 2853 } 2854 return NULL; 2855 } 2856 2857 clang::DeclContext * 2858 SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die) 2859 { 2860 // If this DIE has a specification, or an abstract origin, then trace to those. 2861 2862 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET); 2863 if (die_offset != DW_INVALID_OFFSET) 2864 return GetClangDeclContextForDIEOffset (sc, die_offset); 2865 2866 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET); 2867 if (die_offset != DW_INVALID_OFFSET) 2868 return GetClangDeclContextForDIEOffset (sc, die_offset); 2869 2870 // This is the DIE we want. Parse it, then query our map. 2871 2872 ParseType(sc, curr_cu, die, NULL); 2873 2874 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die); 2875 if (pos != m_die_to_decl_ctx.end()) 2876 return pos->second; 2877 else 2878 return NULL; 2879 } 2880 2881 clang::DeclContext * 2882 SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die) 2883 { 2884 if (m_clang_tu_decl == NULL) 2885 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl(); 2886 2887 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x )\n", die->GetOffset()); 2888 const DWARFDebugInfoEntry * const decl_die = die; 2889 clang::DeclContext *decl_ctx = NULL; 2890 2891 while (die != NULL) 2892 { 2893 // If this is the original DIE that we are searching for a declaration 2894 // for, then don't look in the cache as we don't want our own decl 2895 // context to be our decl context... 2896 if (decl_die != die) 2897 { 2898 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die); 2899 if (pos != m_die_to_decl_ctx.end()) 2900 { 2901 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); 2902 return pos->second; 2903 } 2904 2905 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) checking parent 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); 2906 2907 switch (die->Tag()) 2908 { 2909 case DW_TAG_namespace: 2910 { 2911 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL); 2912 if (namespace_name) 2913 { 2914 Declaration decl; // TODO: fill in the decl object 2915 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (curr_cu, die)); 2916 if (namespace_decl) 2917 { 2918 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); 2919 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die); 2920 } 2921 return namespace_decl; 2922 } 2923 } 2924 break; 2925 2926 case DW_TAG_structure_type: 2927 case DW_TAG_union_type: 2928 case DW_TAG_class_type: 2929 { 2930 Type* type = ResolveType (curr_cu, die); 2931 pos = m_die_to_decl_ctx.find(die); 2932 if (pos != m_die_to_decl_ctx.end()) 2933 { 2934 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); 2935 return pos->second; 2936 } 2937 else 2938 { 2939 if (type) 2940 { 2941 decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ()); 2942 if (decl_ctx) 2943 return decl_ctx; 2944 } 2945 } 2946 } 2947 break; 2948 2949 default: 2950 break; 2951 } 2952 } 2953 2954 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET); 2955 if (die_offset != DW_INVALID_OFFSET) 2956 { 2957 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) check DW_AT_specification 0x%8.8x\n", decl_die->GetOffset(), die_offset); 2958 decl_ctx = GetClangDeclContextContainingDIEOffset (die_offset); 2959 if (decl_ctx != m_clang_tu_decl) 2960 return decl_ctx; 2961 } 2962 2963 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET); 2964 if (die_offset != DW_INVALID_OFFSET) 2965 { 2966 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) check DW_AT_abstract_origin 0x%8.8x\n", decl_die->GetOffset(), die_offset); 2967 decl_ctx = GetClangDeclContextContainingDIEOffset (die_offset); 2968 if (decl_ctx != m_clang_tu_decl) 2969 return decl_ctx; 2970 } 2971 2972 die = die->GetParent(); 2973 } 2974 // Right now we have only one translation unit per module... 2975 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), curr_cu->GetFirstDIEOffset()); 2976 return m_clang_tu_decl; 2977 } 2978 2979 // This function can be used when a DIE is found that is a forward declaration 2980 // DIE and we want to try and find a type that has the complete definition. 2981 TypeSP 2982 SymbolFileDWARF::FindDefinitionTypeForDIE ( 2983 DWARFCompileUnit* cu, 2984 const DWARFDebugInfoEntry *die, 2985 const ConstString &type_name 2986 ) 2987 { 2988 TypeSP type_sp; 2989 2990 if (cu == NULL || die == NULL || !type_name) 2991 return type_sp; 2992 2993 if (!m_indexed) 2994 Index (); 2995 2996 const dw_tag_t type_tag = die->Tag(); 2997 std::vector<NameToDIE::Info> die_info_array; 2998 const size_t num_matches = m_type_index.Find (type_name, die_info_array); 2999 if (num_matches > 0) 3000 { 3001 DWARFCompileUnit* type_cu = NULL; 3002 DWARFCompileUnit* curr_cu = cu; 3003 DWARFDebugInfo *info = DebugInfo(); 3004 for (size_t i=0; i<num_matches; ++i) 3005 { 3006 type_cu = info->GetCompileUnitAtIndex (die_info_array[i].cu_idx); 3007 3008 if (type_cu != curr_cu) 3009 { 3010 type_cu->ExtractDIEsIfNeeded (false); 3011 curr_cu = type_cu; 3012 } 3013 3014 DWARFDebugInfoEntry *type_die = type_cu->GetDIEAtIndexUnchecked (die_info_array[i].die_idx); 3015 3016 if (type_die != die && type_die->Tag() == type_tag) 3017 { 3018 // Hold off on comparing parent DIE tags until 3019 // we know what happens with stuff in namespaces 3020 // for gcc and clang... 3021 //DWARFDebugInfoEntry *parent_die = die->GetParent(); 3022 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent(); 3023 //if (parent_die->Tag() == parent_type_die->Tag()) 3024 { 3025 Type *resolved_type = ResolveType (type_cu, type_die, false); 3026 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) 3027 { 3028 DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n", 3029 die->GetOffset(), 3030 curr_cu->GetOffset(), 3031 m_obj_file->GetFileSpec().GetFilename().AsCString(), 3032 type_die->GetOffset(), 3033 type_cu->GetOffset()); 3034 3035 m_die_to_type[die] = resolved_type; 3036 type_sp = GetTypeList()->FindType(resolved_type->GetID()); 3037 if (!type_sp) 3038 { 3039 DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset()); 3040 } 3041 break; 3042 } 3043 } 3044 } 3045 } 3046 } 3047 return type_sp; 3048 } 3049 3050 TypeSP 3051 SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr) 3052 { 3053 TypeSP type_sp; 3054 3055 if (type_is_new_ptr) 3056 *type_is_new_ptr = false; 3057 3058 AccessType accessibility = eAccessNone; 3059 if (die != NULL) 3060 { 3061 Type *type_ptr = m_die_to_type.lookup (die); 3062 TypeList* type_list = GetTypeList(); 3063 if (type_ptr == NULL) 3064 { 3065 ClangASTContext &ast = GetClangASTContext(); 3066 if (type_is_new_ptr) 3067 *type_is_new_ptr = true; 3068 3069 const dw_tag_t tag = die->Tag(); 3070 3071 bool is_forward_declaration = false; 3072 DWARFDebugInfoEntry::Attributes attributes; 3073 const char *type_name_cstr = NULL; 3074 ConstString type_name_const_str; 3075 Type::ResolveState resolve_state = Type::eResolveStateUnresolved; 3076 size_t byte_size = 0; 3077 bool byte_size_valid = false; 3078 Declaration decl; 3079 3080 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID; 3081 clang_type_t clang_type = NULL; 3082 3083 dw_attr_t attr; 3084 3085 switch (tag) 3086 { 3087 case DW_TAG_base_type: 3088 case DW_TAG_pointer_type: 3089 case DW_TAG_reference_type: 3090 case DW_TAG_typedef: 3091 case DW_TAG_const_type: 3092 case DW_TAG_restrict_type: 3093 case DW_TAG_volatile_type: 3094 { 3095 // Set a bit that lets us know that we are currently parsing this 3096 m_die_to_type[die] = DIE_IS_BEING_PARSED; 3097 3098 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3099 uint32_t encoding = 0; 3100 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 3101 3102 if (num_attributes > 0) 3103 { 3104 uint32_t i; 3105 for (i=0; i<num_attributes; ++i) 3106 { 3107 attr = attributes.AttributeAtIndex(i); 3108 DWARFFormValue form_value; 3109 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3110 { 3111 switch (attr) 3112 { 3113 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3114 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3115 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3116 case DW_AT_name: 3117 3118 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3119 // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't 3120 // include the "&"... 3121 if (tag == DW_TAG_reference_type) 3122 { 3123 if (strchr (type_name_cstr, '&') == NULL) 3124 type_name_cstr = NULL; 3125 } 3126 if (type_name_cstr) 3127 type_name_const_str.SetCString(type_name_cstr); 3128 break; 3129 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break; 3130 case DW_AT_encoding: encoding = form_value.Unsigned(); break; 3131 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 3132 default: 3133 case DW_AT_sibling: 3134 break; 3135 } 3136 } 3137 } 3138 } 3139 3140 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") type => 0x%8.8x\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid); 3141 3142 switch (tag) 3143 { 3144 default: 3145 break; 3146 3147 case DW_TAG_base_type: 3148 resolve_state = Type::eResolveStateFull; 3149 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, 3150 encoding, 3151 byte_size * 8); 3152 break; 3153 3154 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break; 3155 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break; 3156 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break; 3157 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break; 3158 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break; 3159 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break; 3160 } 3161 3162 if (type_name_cstr != NULL && sc.comp_unit != NULL && 3163 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus)) 3164 { 3165 static ConstString g_objc_type_name_id("id"); 3166 static ConstString g_objc_type_name_Class("Class"); 3167 static ConstString g_objc_type_name_selector("SEL"); 3168 3169 if (type_name_const_str == g_objc_type_name_id) 3170 { 3171 clang_type = ast.GetBuiltInType_objc_id(); 3172 resolve_state = Type::eResolveStateFull; 3173 3174 } 3175 else if (type_name_const_str == g_objc_type_name_Class) 3176 { 3177 clang_type = ast.GetBuiltInType_objc_Class(); 3178 resolve_state = Type::eResolveStateFull; 3179 } 3180 else if (type_name_const_str == g_objc_type_name_selector) 3181 { 3182 clang_type = ast.GetBuiltInType_objc_selector(); 3183 resolve_state = Type::eResolveStateFull; 3184 } 3185 } 3186 3187 type_sp.reset( new Type (die->GetOffset(), 3188 this, 3189 type_name_const_str, 3190 byte_size, 3191 NULL, 3192 encoding_uid, 3193 encoding_data_type, 3194 &decl, 3195 clang_type, 3196 resolve_state)); 3197 3198 m_die_to_type[die] = type_sp.get(); 3199 3200 // Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false); 3201 // if (encoding_type != NULL) 3202 // { 3203 // if (encoding_type != DIE_IS_BEING_PARSED) 3204 // type_sp->SetEncodingType(encoding_type); 3205 // else 3206 // m_indirect_fixups.push_back(type_sp.get()); 3207 // } 3208 } 3209 break; 3210 3211 case DW_TAG_structure_type: 3212 case DW_TAG_union_type: 3213 case DW_TAG_class_type: 3214 { 3215 // Set a bit that lets us know that we are currently parsing this 3216 m_die_to_type[die] = DIE_IS_BEING_PARSED; 3217 3218 LanguageType class_language = eLanguageTypeUnknown; 3219 //bool struct_is_class = false; 3220 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3221 if (num_attributes > 0) 3222 { 3223 uint32_t i; 3224 for (i=0; i<num_attributes; ++i) 3225 { 3226 attr = attributes.AttributeAtIndex(i); 3227 DWARFFormValue form_value; 3228 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3229 { 3230 switch (attr) 3231 { 3232 case DW_AT_decl_file: 3233 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); 3234 break; 3235 3236 case DW_AT_decl_line: 3237 decl.SetLine(form_value.Unsigned()); 3238 break; 3239 3240 case DW_AT_decl_column: 3241 decl.SetColumn(form_value.Unsigned()); 3242 break; 3243 3244 case DW_AT_name: 3245 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3246 type_name_const_str.SetCString(type_name_cstr); 3247 break; 3248 3249 case DW_AT_byte_size: 3250 byte_size = form_value.Unsigned(); 3251 byte_size_valid = true; 3252 break; 3253 3254 case DW_AT_accessibility: 3255 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); 3256 break; 3257 3258 case DW_AT_declaration: 3259 is_forward_declaration = form_value.Unsigned() != 0; 3260 break; 3261 3262 case DW_AT_APPLE_runtime_class: 3263 class_language = (LanguageType)form_value.Signed(); 3264 break; 3265 3266 case DW_AT_allocated: 3267 case DW_AT_associated: 3268 case DW_AT_data_location: 3269 case DW_AT_description: 3270 case DW_AT_start_scope: 3271 case DW_AT_visibility: 3272 default: 3273 case DW_AT_sibling: 3274 break; 3275 } 3276 } 3277 } 3278 } 3279 3280 UniqueDWARFASTType unique_ast_entry; 3281 if (decl.IsValid()) 3282 { 3283 if (GetUniqueDWARFASTTypeMap().Find (type_name_const_str, 3284 this, 3285 dwarf_cu, 3286 die, 3287 decl, 3288 byte_size_valid ? byte_size : -1, 3289 unique_ast_entry)) 3290 { 3291 // We have already parsed this type or from another 3292 // compile unit. GCC loves to use the "one definition 3293 // rule" which can result in multiple definitions 3294 // of the same class over and over in each compile 3295 // unit. 3296 type_sp = unique_ast_entry.m_type_sp; 3297 if (type_sp) 3298 { 3299 m_die_to_type[die] = type_sp.get(); 3300 return type_sp; 3301 } 3302 } 3303 } 3304 3305 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr); 3306 3307 int tag_decl_kind = -1; 3308 AccessType default_accessibility = eAccessNone; 3309 if (tag == DW_TAG_structure_type) 3310 { 3311 tag_decl_kind = clang::TTK_Struct; 3312 default_accessibility = eAccessPublic; 3313 } 3314 else if (tag == DW_TAG_union_type) 3315 { 3316 tag_decl_kind = clang::TTK_Union; 3317 default_accessibility = eAccessPublic; 3318 } 3319 else if (tag == DW_TAG_class_type) 3320 { 3321 tag_decl_kind = clang::TTK_Class; 3322 default_accessibility = eAccessPrivate; 3323 } 3324 3325 3326 if (is_forward_declaration) 3327 { 3328 // We have a forward declaration to a type and we need 3329 // to try and find a full declaration. We look in the 3330 // current type index just in case we have a forward 3331 // declaration followed by an actual declarations in the 3332 // DWARF. If this fails, we need to look elsewhere... 3333 3334 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); 3335 3336 if (!type_sp && m_debug_map_symfile) 3337 { 3338 // We weren't able to find a full declaration in 3339 // this DWARF, see if we have a declaration anywhere 3340 // else... 3341 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); 3342 } 3343 3344 if (type_sp) 3345 { 3346 // We found a real definition for this type elsewhere 3347 // so lets use it and cache the fact that we found 3348 // a complete type for this die 3349 m_die_to_type[die] = type_sp.get(); 3350 return type_sp; 3351 } 3352 } 3353 assert (tag_decl_kind != -1); 3354 bool clang_type_was_created = false; 3355 clang_type = m_forward_decl_die_to_clang_type.lookup (die); 3356 if (clang_type == NULL) 3357 { 3358 clang_type_was_created = true; 3359 clang_type = ast.CreateRecordType (type_name_cstr, 3360 tag_decl_kind, 3361 GetClangDeclContextContainingDIE (dwarf_cu, die), 3362 class_language); 3363 } 3364 3365 // Store a forward declaration to this class type in case any 3366 // parameters in any class methods need it for the clang 3367 // types for function prototypes. 3368 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); 3369 type_sp.reset (new Type (die->GetOffset(), 3370 this, 3371 type_name_const_str, 3372 byte_size, 3373 NULL, 3374 LLDB_INVALID_UID, 3375 Type::eEncodingIsUID, 3376 &decl, 3377 clang_type, 3378 Type::eResolveStateForward)); 3379 3380 3381 // Add our type to the unique type map so we don't 3382 // end up creating many copies of the same type over 3383 // and over in the ASTContext for our module 3384 unique_ast_entry.m_type_sp = type_sp; 3385 unique_ast_entry.m_symfile = this; 3386 unique_ast_entry.m_cu = dwarf_cu; 3387 unique_ast_entry.m_die = die; 3388 unique_ast_entry.m_declaration = decl; 3389 GetUniqueDWARFASTTypeMap().Insert (type_name_const_str, 3390 unique_ast_entry); 3391 3392 if (die->HasChildren() == false && is_forward_declaration == false) 3393 { 3394 // No children for this struct/union/class, lets finish it 3395 ast.StartTagDeclarationDefinition (clang_type); 3396 ast.CompleteTagDeclarationDefinition (clang_type); 3397 } 3398 else if (clang_type_was_created) 3399 { 3400 // Leave this as a forward declaration until we need 3401 // to know the details of the type. lldb_private::Type 3402 // will automatically call the SymbolFile virtual function 3403 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)" 3404 // When the definition needs to be defined. 3405 m_forward_decl_die_to_clang_type[die] = clang_type; 3406 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die; 3407 ClangASTContext::SetHasExternalStorage (clang_type, true); 3408 } 3409 } 3410 break; 3411 3412 case DW_TAG_enumeration_type: 3413 { 3414 // Set a bit that lets us know that we are currently parsing this 3415 m_die_to_type[die] = DIE_IS_BEING_PARSED; 3416 3417 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET; 3418 3419 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3420 if (num_attributes > 0) 3421 { 3422 uint32_t i; 3423 3424 for (i=0; i<num_attributes; ++i) 3425 { 3426 attr = attributes.AttributeAtIndex(i); 3427 DWARFFormValue form_value; 3428 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3429 { 3430 switch (attr) 3431 { 3432 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3433 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3434 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3435 case DW_AT_name: 3436 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3437 type_name_const_str.SetCString(type_name_cstr); 3438 break; 3439 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 3440 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break; 3441 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 3442 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 3443 case DW_AT_allocated: 3444 case DW_AT_associated: 3445 case DW_AT_bit_stride: 3446 case DW_AT_byte_stride: 3447 case DW_AT_data_location: 3448 case DW_AT_description: 3449 case DW_AT_start_scope: 3450 case DW_AT_visibility: 3451 case DW_AT_specification: 3452 case DW_AT_abstract_origin: 3453 case DW_AT_sibling: 3454 break; 3455 } 3456 } 3457 } 3458 3459 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr); 3460 3461 clang_type_t enumerator_clang_type = NULL; 3462 clang_type = m_forward_decl_die_to_clang_type.lookup (die); 3463 if (clang_type == NULL) 3464 { 3465 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, 3466 DW_ATE_signed, 3467 byte_size * 8); 3468 clang_type = ast.CreateEnumerationType (type_name_cstr, 3469 GetClangDeclContextContainingDIE (dwarf_cu, die), 3470 decl, 3471 enumerator_clang_type); 3472 } 3473 else 3474 { 3475 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type); 3476 assert (enumerator_clang_type != NULL); 3477 } 3478 3479 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); 3480 3481 type_sp.reset( new Type (die->GetOffset(), 3482 this, 3483 type_name_const_str, 3484 byte_size, 3485 NULL, 3486 encoding_uid, 3487 Type::eEncodingIsUID, 3488 &decl, 3489 clang_type, 3490 Type::eResolveStateForward)); 3491 3492 #if LEAVE_ENUMS_FORWARD_DECLARED 3493 // Leave this as a forward declaration until we need 3494 // to know the details of the type. lldb_private::Type 3495 // will automatically call the SymbolFile virtual function 3496 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)" 3497 // When the definition needs to be defined. 3498 m_forward_decl_die_to_clang_type[die] = clang_type; 3499 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die; 3500 ClangASTContext::SetHasExternalStorage (clang_type, true); 3501 #else 3502 ast.StartTagDeclarationDefinition (clang_type); 3503 if (die->HasChildren()) 3504 { 3505 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu)); 3506 ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die); 3507 } 3508 ast.CompleteTagDeclarationDefinition (clang_type); 3509 #endif 3510 } 3511 } 3512 break; 3513 3514 case DW_TAG_inlined_subroutine: 3515 case DW_TAG_subprogram: 3516 case DW_TAG_subroutine_type: 3517 { 3518 // Set a bit that lets us know that we are currently parsing this 3519 m_die_to_type[die] = DIE_IS_BEING_PARSED; 3520 3521 const char *mangled = NULL; 3522 dw_offset_t type_die_offset = DW_INVALID_OFFSET; 3523 bool is_variadic = false; 3524 bool is_inline = false; 3525 bool is_static = false; 3526 bool is_virtual = false; 3527 bool is_explicit = false; 3528 3529 unsigned type_quals = 0; 3530 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern 3531 3532 3533 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3534 if (num_attributes > 0) 3535 { 3536 uint32_t i; 3537 for (i=0; i<num_attributes; ++i) 3538 { 3539 attr = attributes.AttributeAtIndex(i); 3540 DWARFFormValue form_value; 3541 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3542 { 3543 switch (attr) 3544 { 3545 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3546 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3547 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3548 case DW_AT_name: 3549 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3550 type_name_const_str.SetCString(type_name_cstr); 3551 break; 3552 3553 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break; 3554 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; 3555 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 3556 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 3557 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break; 3558 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break; 3559 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break; 3560 3561 case DW_AT_external: 3562 if (form_value.Unsigned()) 3563 { 3564 if (storage == clang::SC_None) 3565 storage = clang::SC_Extern; 3566 else 3567 storage = clang::SC_PrivateExtern; 3568 } 3569 break; 3570 3571 case DW_AT_allocated: 3572 case DW_AT_associated: 3573 case DW_AT_address_class: 3574 case DW_AT_artificial: 3575 case DW_AT_calling_convention: 3576 case DW_AT_data_location: 3577 case DW_AT_elemental: 3578 case DW_AT_entry_pc: 3579 case DW_AT_frame_base: 3580 case DW_AT_high_pc: 3581 case DW_AT_low_pc: 3582 case DW_AT_object_pointer: 3583 case DW_AT_prototyped: 3584 case DW_AT_pure: 3585 case DW_AT_ranges: 3586 case DW_AT_recursive: 3587 case DW_AT_return_addr: 3588 case DW_AT_segment: 3589 case DW_AT_specification: 3590 case DW_AT_start_scope: 3591 case DW_AT_static_link: 3592 case DW_AT_trampoline: 3593 case DW_AT_visibility: 3594 case DW_AT_vtable_elem_location: 3595 case DW_AT_abstract_origin: 3596 case DW_AT_description: 3597 case DW_AT_sibling: 3598 break; 3599 } 3600 } 3601 } 3602 } 3603 3604 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr); 3605 3606 clang_type_t return_clang_type = NULL; 3607 Type *func_type = NULL; 3608 3609 if (type_die_offset != DW_INVALID_OFFSET) 3610 func_type = ResolveTypeUID(type_die_offset); 3611 3612 if (func_type) 3613 return_clang_type = func_type->GetClangLayoutType(); 3614 else 3615 return_clang_type = ast.GetBuiltInType_void(); 3616 3617 3618 std::vector<clang_type_t> function_param_types; 3619 std::vector<clang::ParmVarDecl*> function_param_decls; 3620 3621 // Parse the function children for the parameters 3622 3623 const DWARFDebugInfoEntry *class_die = die->GetParent(); 3624 if (class_die && (class_die->Tag() == DW_TAG_structure_type || 3625 class_die->Tag() == DW_TAG_class_type)) 3626 is_static = true; 3627 3628 if (die->HasChildren()) 3629 { 3630 bool skip_artificial = true; 3631 ParseChildParameters (sc, 3632 type_sp, 3633 dwarf_cu, 3634 die, 3635 skip_artificial, 3636 is_static, 3637 type_list, 3638 function_param_types, 3639 function_param_decls, 3640 type_quals); 3641 } 3642 3643 // clang_type will get the function prototype clang type after this call 3644 clang_type = ast.CreateFunctionType (return_clang_type, 3645 &function_param_types[0], 3646 function_param_types.size(), 3647 is_variadic, 3648 type_quals); 3649 3650 if (type_name_cstr) 3651 { 3652 bool type_handled = false; 3653 const DWARFDebugInfoEntry *parent_die = die->GetParent(); 3654 if (tag == DW_TAG_subprogram) 3655 { 3656 if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+')) 3657 { 3658 // We need to find the DW_TAG_class_type or 3659 // DW_TAG_struct_type by name so we can add this 3660 // as a member function of the class. 3661 const char *class_name_start = type_name_cstr + 2; 3662 const char *class_name_end = ::strchr (class_name_start, ' '); 3663 SymbolContext empty_sc; 3664 clang_type_t class_opaque_type = NULL; 3665 if (class_name_start < class_name_end) 3666 { 3667 ConstString class_name (class_name_start, class_name_end - class_name_start); 3668 TypeList types; 3669 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types); 3670 if (match_count > 0) 3671 { 3672 for (uint32_t i=0; i<match_count; ++i) 3673 { 3674 Type *type = types.GetTypeAtIndex (i).get(); 3675 clang_type_t type_clang_forward_type = type->GetClangForwardType(); 3676 if (ClangASTContext::IsObjCClassType (type_clang_forward_type)) 3677 { 3678 class_opaque_type = type_clang_forward_type; 3679 break; 3680 } 3681 } 3682 } 3683 } 3684 3685 if (class_opaque_type) 3686 { 3687 // If accessibility isn't set to anything valid, assume public for 3688 // now... 3689 if (accessibility == eAccessNone) 3690 accessibility = eAccessPublic; 3691 3692 clang::ObjCMethodDecl *objc_method_decl; 3693 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type, 3694 type_name_cstr, 3695 clang_type, 3696 accessibility); 3697 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die); 3698 type_handled = objc_method_decl != NULL; 3699 } 3700 } 3701 else if (parent_die->Tag() == DW_TAG_class_type || 3702 parent_die->Tag() == DW_TAG_structure_type) 3703 { 3704 // Look at the parent of this DIE and see if is is 3705 // a class or struct and see if this is actually a 3706 // C++ method 3707 Type *class_type = ResolveType (dwarf_cu, parent_die); 3708 if (class_type) 3709 { 3710 clang_type_t class_opaque_type = class_type->GetClangForwardType(); 3711 if (ClangASTContext::IsCXXClassType (class_opaque_type)) 3712 { 3713 // Neither GCC 4.2 nor clang++ currently set a valid accessibility 3714 // in the DWARF for C++ methods... Default to public for now... 3715 if (accessibility == eAccessNone) 3716 accessibility = eAccessPublic; 3717 3718 if (!is_static && !die->HasChildren()) 3719 { 3720 // We have a C++ member function with no children (this pointer!) 3721 // and clang will get mad if we try and make a function that isn't 3722 // well formed in the DWARF, so we will just skip it... 3723 type_handled = true; 3724 } 3725 else 3726 { 3727 clang::CXXMethodDecl *cxx_method_decl; 3728 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type, 3729 type_name_cstr, 3730 clang_type, 3731 accessibility, 3732 is_virtual, 3733 is_static, 3734 is_inline, 3735 is_explicit); 3736 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die); 3737 3738 type_handled = cxx_method_decl != NULL; 3739 } 3740 } 3741 } 3742 } 3743 } 3744 3745 if (!type_handled) 3746 { 3747 // We just have a function that isn't part of a class 3748 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr, 3749 clang_type, 3750 storage, 3751 is_inline); 3752 3753 // Add the decl to our DIE to decl context map 3754 assert (function_decl); 3755 LinkDeclContextToDIE(function_decl, die); 3756 if (!function_param_decls.empty()) 3757 ast.SetFunctionParameters (function_decl, 3758 &function_param_decls.front(), 3759 function_param_decls.size()); 3760 } 3761 } 3762 type_sp.reset( new Type (die->GetOffset(), 3763 this, 3764 type_name_const_str, 3765 0, 3766 NULL, 3767 LLDB_INVALID_UID, 3768 Type::eEncodingIsUID, 3769 &decl, 3770 clang_type, 3771 Type::eResolveStateFull)); 3772 assert(type_sp.get()); 3773 } 3774 break; 3775 3776 case DW_TAG_array_type: 3777 { 3778 // Set a bit that lets us know that we are currently parsing this 3779 m_die_to_type[die] = DIE_IS_BEING_PARSED; 3780 3781 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET; 3782 int64_t first_index = 0; 3783 uint32_t byte_stride = 0; 3784 uint32_t bit_stride = 0; 3785 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3786 3787 if (num_attributes > 0) 3788 { 3789 uint32_t i; 3790 for (i=0; i<num_attributes; ++i) 3791 { 3792 attr = attributes.AttributeAtIndex(i); 3793 DWARFFormValue form_value; 3794 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3795 { 3796 switch (attr) 3797 { 3798 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3799 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3800 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3801 case DW_AT_name: 3802 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3803 type_name_const_str.SetCString(type_name_cstr); 3804 break; 3805 3806 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; 3807 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break; 3808 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break; 3809 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break; 3810 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 3811 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 3812 case DW_AT_allocated: 3813 case DW_AT_associated: 3814 case DW_AT_data_location: 3815 case DW_AT_description: 3816 case DW_AT_ordering: 3817 case DW_AT_start_scope: 3818 case DW_AT_visibility: 3819 case DW_AT_specification: 3820 case DW_AT_abstract_origin: 3821 case DW_AT_sibling: 3822 break; 3823 } 3824 } 3825 } 3826 3827 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr); 3828 3829 Type *element_type = ResolveTypeUID(type_die_offset); 3830 3831 if (element_type) 3832 { 3833 std::vector<uint64_t> element_orders; 3834 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride); 3835 // We have an array that claims to have no members, lets give it at least one member... 3836 if (element_orders.empty()) 3837 element_orders.push_back (1); 3838 if (byte_stride == 0 && bit_stride == 0) 3839 byte_stride = element_type->GetByteSize(); 3840 clang_type_t array_element_type = element_type->GetClangFullType(); 3841 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; 3842 uint64_t num_elements = 0; 3843 std::vector<uint64_t>::const_reverse_iterator pos; 3844 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend(); 3845 for (pos = element_orders.rbegin(); pos != end; ++pos) 3846 { 3847 num_elements = *pos; 3848 clang_type = ast.CreateArrayType (array_element_type, 3849 num_elements, 3850 num_elements * array_element_bit_stride); 3851 array_element_type = clang_type; 3852 array_element_bit_stride = array_element_bit_stride * num_elements; 3853 } 3854 ConstString empty_name; 3855 type_sp.reset( new Type (die->GetOffset(), 3856 this, 3857 empty_name, 3858 array_element_bit_stride / 8, 3859 NULL, 3860 type_die_offset, 3861 Type::eEncodingIsUID, 3862 &decl, 3863 clang_type, 3864 Type::eResolveStateFull)); 3865 type_sp->SetEncodingType (element_type); 3866 } 3867 } 3868 } 3869 break; 3870 3871 case DW_TAG_ptr_to_member_type: 3872 { 3873 dw_offset_t type_die_offset = DW_INVALID_OFFSET; 3874 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET; 3875 3876 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3877 3878 if (num_attributes > 0) { 3879 uint32_t i; 3880 for (i=0; i<num_attributes; ++i) 3881 { 3882 attr = attributes.AttributeAtIndex(i); 3883 DWARFFormValue form_value; 3884 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3885 { 3886 switch (attr) 3887 { 3888 case DW_AT_type: 3889 type_die_offset = form_value.Reference(dwarf_cu); break; 3890 case DW_AT_containing_type: 3891 containing_type_die_offset = form_value.Reference(dwarf_cu); break; 3892 } 3893 } 3894 } 3895 3896 Type *pointee_type = ResolveTypeUID(type_die_offset); 3897 Type *class_type = ResolveTypeUID(containing_type_die_offset); 3898 3899 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType(); 3900 clang_type_t class_clang_type = class_type->GetClangLayoutType(); 3901 3902 clang_type = ast.CreateMemberPointerType(pointee_clang_type, 3903 class_clang_type); 3904 3905 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(), 3906 clang_type) / 8; 3907 3908 type_sp.reset( new Type (die->GetOffset(), 3909 this, 3910 type_name_const_str, 3911 byte_size, 3912 NULL, 3913 LLDB_INVALID_UID, 3914 Type::eEncodingIsUID, 3915 NULL, 3916 clang_type, 3917 Type::eResolveStateForward)); 3918 } 3919 3920 break; 3921 } 3922 default: 3923 assert(false && "Unhandled type tag!"); 3924 break; 3925 } 3926 3927 if (type_sp.get()) 3928 { 3929 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die); 3930 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 3931 3932 SymbolContextScope * symbol_context_scope = NULL; 3933 if (sc_parent_tag == DW_TAG_compile_unit) 3934 { 3935 symbol_context_scope = sc.comp_unit; 3936 } 3937 else if (sc.function != NULL) 3938 { 3939 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset()); 3940 if (symbol_context_scope == NULL) 3941 symbol_context_scope = sc.function; 3942 } 3943 3944 if (symbol_context_scope != NULL) 3945 { 3946 type_sp->SetSymbolContextScope(symbol_context_scope); 3947 } 3948 3949 // We are ready to put this type into the uniqued list up at the module level 3950 type_list->Insert (type_sp); 3951 3952 m_die_to_type[die] = type_sp.get(); 3953 } 3954 } 3955 else if (type_ptr != DIE_IS_BEING_PARSED) 3956 { 3957 type_sp = type_list->FindType(type_ptr->GetID()); 3958 } 3959 } 3960 return type_sp; 3961 } 3962 3963 size_t 3964 SymbolFileDWARF::ParseTypes 3965 ( 3966 const SymbolContext& sc, 3967 DWARFCompileUnit* dwarf_cu, 3968 const DWARFDebugInfoEntry *die, 3969 bool parse_siblings, 3970 bool parse_children 3971 ) 3972 { 3973 size_t types_added = 0; 3974 while (die != NULL) 3975 { 3976 bool type_is_new = false; 3977 if (ParseType(sc, dwarf_cu, die, &type_is_new).get()) 3978 { 3979 if (type_is_new) 3980 ++types_added; 3981 } 3982 3983 if (parse_children && die->HasChildren()) 3984 { 3985 if (die->Tag() == DW_TAG_subprogram) 3986 { 3987 SymbolContext child_sc(sc); 3988 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get(); 3989 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true); 3990 } 3991 else 3992 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true); 3993 } 3994 3995 if (parse_siblings) 3996 die = die->GetSibling(); 3997 else 3998 die = NULL; 3999 } 4000 return types_added; 4001 } 4002 4003 4004 size_t 4005 SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc) 4006 { 4007 assert(sc.comp_unit && sc.function); 4008 size_t functions_added = 0; 4009 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 4010 if (dwarf_cu) 4011 { 4012 dw_offset_t function_die_offset = sc.function->GetID(); 4013 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset); 4014 if (function_die) 4015 { 4016 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true); 4017 } 4018 } 4019 4020 return functions_added; 4021 } 4022 4023 4024 size_t 4025 SymbolFileDWARF::ParseTypes (const SymbolContext &sc) 4026 { 4027 // At least a compile unit must be valid 4028 assert(sc.comp_unit); 4029 size_t types_added = 0; 4030 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 4031 if (dwarf_cu) 4032 { 4033 if (sc.function) 4034 { 4035 dw_offset_t function_die_offset = sc.function->GetID(); 4036 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset); 4037 if (func_die && func_die->HasChildren()) 4038 { 4039 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true); 4040 } 4041 } 4042 else 4043 { 4044 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE(); 4045 if (dwarf_cu_die && dwarf_cu_die->HasChildren()) 4046 { 4047 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true); 4048 } 4049 } 4050 } 4051 4052 return types_added; 4053 } 4054 4055 size_t 4056 SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc) 4057 { 4058 if (sc.comp_unit != NULL) 4059 { 4060 DWARFDebugInfo* info = DebugInfo(); 4061 if (info == NULL) 4062 return 0; 4063 4064 uint32_t cu_idx = UINT32_MAX; 4065 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get(); 4066 4067 if (dwarf_cu == NULL) 4068 return 0; 4069 4070 if (sc.function) 4071 { 4072 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID()); 4073 4074 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS); 4075 assert (func_lo_pc != DW_INVALID_ADDRESS); 4076 4077 const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true); 4078 4079 // Let all blocks know they have parse all their variables 4080 sc.function->GetBlock (false).SetDidParseVariables (true, true); 4081 4082 return num_variables; 4083 } 4084 else if (sc.comp_unit) 4085 { 4086 uint32_t vars_added = 0; 4087 VariableListSP variables (sc.comp_unit->GetVariableList(false)); 4088 4089 if (variables.get() == NULL) 4090 { 4091 variables.reset(new VariableList()); 4092 sc.comp_unit->SetVariableList(variables); 4093 4094 // Index if we already haven't to make sure the compile units 4095 // get indexed and make their global DIE index list 4096 if (!m_indexed) 4097 Index (); 4098 4099 std::vector<NameToDIE::Info> global_die_info_array; 4100 const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (cu_idx, global_die_info_array); 4101 for (size_t idx=0; idx<num_globals; ++idx) 4102 { 4103 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetDIEAtIndexUnchecked(global_die_info_array[idx].die_idx), LLDB_INVALID_ADDRESS)); 4104 if (var_sp) 4105 { 4106 variables->AddVariableIfUnique (var_sp); 4107 ++vars_added; 4108 } 4109 } 4110 } 4111 return vars_added; 4112 } 4113 } 4114 return 0; 4115 } 4116 4117 4118 VariableSP 4119 SymbolFileDWARF::ParseVariableDIE 4120 ( 4121 const SymbolContext& sc, 4122 DWARFCompileUnit* dwarf_cu, 4123 const DWARFDebugInfoEntry *die, 4124 const lldb::addr_t func_low_pc 4125 ) 4126 { 4127 4128 VariableSP var_sp (m_die_to_variable_sp[die]); 4129 if (var_sp) 4130 return var_sp; // Already been parsed! 4131 4132 const dw_tag_t tag = die->Tag(); 4133 DWARFDebugInfoEntry::Attributes attributes; 4134 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 4135 if (num_attributes > 0) 4136 { 4137 const char *name = NULL; 4138 const char *mangled = NULL; 4139 Declaration decl; 4140 uint32_t i; 4141 Type *var_type = NULL; 4142 DWARFExpression location; 4143 bool is_external = false; 4144 bool is_artificial = false; 4145 bool location_is_const_value_data = false; 4146 AccessType accessibility = eAccessNone; 4147 4148 for (i=0; i<num_attributes; ++i) 4149 { 4150 dw_attr_t attr = attributes.AttributeAtIndex(i); 4151 DWARFFormValue form_value; 4152 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 4153 { 4154 switch (attr) 4155 { 4156 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 4157 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 4158 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 4159 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 4160 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break; 4161 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break; 4162 case DW_AT_external: is_external = form_value.Unsigned() != 0; break; 4163 case DW_AT_const_value: 4164 location_is_const_value_data = true; 4165 // Fall through... 4166 case DW_AT_location: 4167 { 4168 if (form_value.BlockData()) 4169 { 4170 const DataExtractor& debug_info_data = get_debug_info_data(); 4171 4172 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 4173 uint32_t block_length = form_value.Unsigned(); 4174 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length); 4175 } 4176 else 4177 { 4178 const DataExtractor& debug_loc_data = get_debug_loc_data(); 4179 const dw_offset_t debug_loc_offset = form_value.Unsigned(); 4180 4181 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset); 4182 if (loc_list_length > 0) 4183 { 4184 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length); 4185 assert (func_low_pc != LLDB_INVALID_ADDRESS); 4186 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress()); 4187 } 4188 } 4189 } 4190 break; 4191 4192 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break; 4193 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 4194 case DW_AT_declaration: 4195 case DW_AT_description: 4196 case DW_AT_endianity: 4197 case DW_AT_segment: 4198 case DW_AT_start_scope: 4199 case DW_AT_visibility: 4200 default: 4201 case DW_AT_abstract_origin: 4202 case DW_AT_sibling: 4203 case DW_AT_specification: 4204 break; 4205 } 4206 } 4207 } 4208 4209 if (location.IsValid()) 4210 { 4211 assert(var_type != DIE_IS_BEING_PARSED); 4212 4213 ValueType scope = eValueTypeInvalid; 4214 4215 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die); 4216 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 4217 4218 if (tag == DW_TAG_formal_parameter) 4219 scope = eValueTypeVariableArgument; 4220 else if (is_external || parent_tag == DW_TAG_compile_unit) 4221 scope = eValueTypeVariableGlobal; 4222 else 4223 scope = eValueTypeVariableLocal; 4224 4225 SymbolContextScope * symbol_context_scope = NULL; 4226 if (parent_tag == DW_TAG_compile_unit) 4227 { 4228 symbol_context_scope = sc.comp_unit; 4229 } 4230 else if (sc.function != NULL) 4231 { 4232 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset()); 4233 if (symbol_context_scope == NULL) 4234 symbol_context_scope = sc.function; 4235 } 4236 4237 assert(symbol_context_scope != NULL); 4238 var_sp.reset (new Variable(die->GetOffset(), 4239 name, 4240 mangled, 4241 var_type, 4242 scope, 4243 symbol_context_scope, 4244 &decl, 4245 location, 4246 is_external, 4247 is_artificial)); 4248 4249 var_sp->SetLocationIsConstantValueData (location_is_const_value_data); 4250 } 4251 } 4252 // Cache var_sp even if NULL (the variable was just a specification or 4253 // was missing vital information to be able to be displayed in the debugger 4254 // (missing location due to optimization, etc)) so we don't re-parse 4255 // this DIE over and over later... 4256 m_die_to_variable_sp[die] = var_sp; 4257 return var_sp; 4258 } 4259 4260 4261 const DWARFDebugInfoEntry * 4262 SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset, 4263 dw_offset_t spec_block_die_offset, 4264 DWARFCompileUnit **result_die_cu_handle) 4265 { 4266 // Give the concrete function die specified by "func_die_offset", find the 4267 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points 4268 // to "spec_block_die_offset" 4269 DWARFDebugInfo* info = DebugInfo(); 4270 4271 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle); 4272 if (die) 4273 { 4274 assert (*result_die_cu_handle); 4275 return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle); 4276 } 4277 return NULL; 4278 } 4279 4280 4281 const DWARFDebugInfoEntry * 4282 SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu, 4283 const DWARFDebugInfoEntry *die, 4284 dw_offset_t spec_block_die_offset, 4285 DWARFCompileUnit **result_die_cu_handle) 4286 { 4287 if (die) 4288 { 4289 switch (die->Tag()) 4290 { 4291 case DW_TAG_subprogram: 4292 case DW_TAG_inlined_subroutine: 4293 case DW_TAG_lexical_block: 4294 { 4295 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset) 4296 { 4297 *result_die_cu_handle = dwarf_cu; 4298 return die; 4299 } 4300 4301 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset) 4302 { 4303 *result_die_cu_handle = dwarf_cu; 4304 return die; 4305 } 4306 } 4307 break; 4308 } 4309 4310 // Give the concrete function die specified by "func_die_offset", find the 4311 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points 4312 // to "spec_block_die_offset" 4313 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling()) 4314 { 4315 const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu, 4316 child_die, 4317 spec_block_die_offset, 4318 result_die_cu_handle); 4319 if (result_die) 4320 return result_die; 4321 } 4322 } 4323 4324 *result_die_cu_handle = NULL; 4325 return NULL; 4326 } 4327 4328 size_t 4329 SymbolFileDWARF::ParseVariables 4330 ( 4331 const SymbolContext& sc, 4332 DWARFCompileUnit* dwarf_cu, 4333 const lldb::addr_t func_low_pc, 4334 const DWARFDebugInfoEntry *orig_die, 4335 bool parse_siblings, 4336 bool parse_children, 4337 VariableList* cc_variable_list 4338 ) 4339 { 4340 if (orig_die == NULL) 4341 return 0; 4342 4343 VariableListSP variable_list_sp; 4344 4345 size_t vars_added = 0; 4346 const DWARFDebugInfoEntry *die = orig_die; 4347 while (die != NULL) 4348 { 4349 dw_tag_t tag = die->Tag(); 4350 4351 // Check to see if we have already parsed this variable or constant? 4352 if (m_die_to_variable_sp[die]) 4353 { 4354 if (cc_variable_list) 4355 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]); 4356 } 4357 else 4358 { 4359 // We haven't already parsed it, lets do that now. 4360 if ((tag == DW_TAG_variable) || 4361 (tag == DW_TAG_constant) || 4362 (tag == DW_TAG_formal_parameter && sc.function)) 4363 { 4364 if (variable_list_sp.get() == NULL) 4365 { 4366 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die); 4367 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 4368 switch (parent_tag) 4369 { 4370 case DW_TAG_compile_unit: 4371 if (sc.comp_unit != NULL) 4372 { 4373 variable_list_sp = sc.comp_unit->GetVariableList(false); 4374 if (variable_list_sp.get() == NULL) 4375 { 4376 variable_list_sp.reset(new VariableList()); 4377 sc.comp_unit->SetVariableList(variable_list_sp); 4378 } 4379 } 4380 else 4381 { 4382 fprintf (stderr, 4383 "error: parent 0x%8.8x %s with no valid compile unit in symbol context for 0x%8.8x %s.\n", 4384 sc_parent_die->GetOffset(), 4385 DW_TAG_value_to_name (parent_tag), 4386 orig_die->GetOffset(), 4387 DW_TAG_value_to_name (orig_die->Tag())); 4388 } 4389 break; 4390 4391 case DW_TAG_subprogram: 4392 case DW_TAG_inlined_subroutine: 4393 case DW_TAG_lexical_block: 4394 if (sc.function != NULL) 4395 { 4396 // Check to see if we already have parsed the variables for the given scope 4397 4398 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset()); 4399 if (block == NULL) 4400 { 4401 // This must be a specification or abstract origin with 4402 // a concrete block couterpart in the current function. We need 4403 // to find the concrete block so we can correctly add the 4404 // variable to it 4405 DWARFCompileUnit *concrete_block_die_cu = dwarf_cu; 4406 const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(), 4407 sc_parent_die->GetOffset(), 4408 &concrete_block_die_cu); 4409 if (concrete_block_die) 4410 block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die->GetOffset()); 4411 } 4412 4413 if (block != NULL) 4414 { 4415 const bool can_create = false; 4416 variable_list_sp = block->GetBlockVariableList (can_create); 4417 if (variable_list_sp.get() == NULL) 4418 { 4419 variable_list_sp.reset(new VariableList()); 4420 block->SetVariableList(variable_list_sp); 4421 } 4422 } 4423 } 4424 break; 4425 4426 default: 4427 fprintf (stderr, 4428 "error: didn't find appropriate parent DIE for variable list for 0x%8.8x %s.\n", 4429 orig_die->GetOffset(), 4430 DW_TAG_value_to_name (orig_die->Tag())); 4431 break; 4432 } 4433 } 4434 4435 if (variable_list_sp) 4436 { 4437 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc)); 4438 if (var_sp) 4439 { 4440 variable_list_sp->AddVariableIfUnique (var_sp); 4441 if (cc_variable_list) 4442 cc_variable_list->AddVariableIfUnique (var_sp); 4443 ++vars_added; 4444 } 4445 } 4446 } 4447 } 4448 4449 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram); 4450 4451 if (!skip_children && parse_children && die->HasChildren()) 4452 { 4453 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list); 4454 } 4455 4456 if (parse_siblings) 4457 die = die->GetSibling(); 4458 else 4459 die = NULL; 4460 } 4461 return vars_added; 4462 } 4463 4464 //------------------------------------------------------------------ 4465 // PluginInterface protocol 4466 //------------------------------------------------------------------ 4467 const char * 4468 SymbolFileDWARF::GetPluginName() 4469 { 4470 return "SymbolFileDWARF"; 4471 } 4472 4473 const char * 4474 SymbolFileDWARF::GetShortPluginName() 4475 { 4476 return GetPluginNameStatic(); 4477 } 4478 4479 uint32_t 4480 SymbolFileDWARF::GetPluginVersion() 4481 { 4482 return 1; 4483 } 4484 4485 void 4486 SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl) 4487 { 4488 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; 4489 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); 4490 if (clang_type) 4491 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); 4492 } 4493 4494 void 4495 SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl) 4496 { 4497 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; 4498 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); 4499 if (clang_type) 4500 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); 4501 } 4502 4503 void 4504 SymbolFileDWARF::DumpIndexes () 4505 { 4506 StreamFile s(stdout, false); 4507 4508 s.Printf ("DWARF index for (%s) '%s/%s':", 4509 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(), 4510 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(), 4511 GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 4512 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s); 4513 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s); 4514 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s); 4515 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s); 4516 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s); 4517 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s); 4518 s.Printf("\nTypes:\n"); m_type_index.Dump (&s); 4519 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s); 4520 } 4521 4522 void 4523 SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context, 4524 const char *name, 4525 llvm::SmallVectorImpl <clang::NamedDecl *> *results) 4526 { 4527 DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context); 4528 4529 if (iter == m_decl_ctx_to_die.end()) 4530 return; 4531 4532 const DWARFDebugInfoEntry *context_die = iter->second; 4533 4534 if (!results) 4535 return; 4536 4537 DWARFDebugInfo* info = DebugInfo(); 4538 4539 std::vector<NameToDIE::Info> die_info_array; 4540 4541 size_t num_matches = m_type_index.Find (ConstString(name), die_info_array); 4542 4543 if (num_matches) 4544 { 4545 for (int i = 0; 4546 i < num_matches; 4547 ++i) 4548 { 4549 DWARFCompileUnit* compile_unit = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); 4550 compile_unit->ExtractDIEsIfNeeded (false); 4551 const DWARFDebugInfoEntry *die = compile_unit->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); 4552 4553 if (die->GetParent() != context_die) 4554 continue; 4555 4556 Type *matching_type = ResolveType (compile_unit, die); 4557 4558 lldb::clang_type_t type = matching_type->GetClangFullType(); 4559 clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type); 4560 4561 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr())) 4562 { 4563 clang::TagDecl *tag_decl = tag_type->getDecl(); 4564 results->push_back(tag_decl); 4565 } 4566 else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr())) 4567 { 4568 clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); 4569 results->push_back(typedef_decl); 4570 } 4571 } 4572 } 4573 } 4574 4575 void 4576 SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton, 4577 const clang::DeclContext *DC, 4578 clang::DeclarationName Name, 4579 llvm::SmallVectorImpl <clang::NamedDecl *> *results) 4580 { 4581 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; 4582 4583 symbol_file_dwarf->SearchDeclContext (DC, Name.getAsString().c_str(), results); 4584 } 4585