SymbolFileDWARF.cpp revision 99309909259eacf4693458bfe44f913c316a09c6
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 71using namespace lldb; 72using namespace lldb_private; 73 74 75static AccessType 76DW_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 88void 89SymbolFileDWARF::Initialize() 90{ 91 LogChannelDWARF::Initialize(); 92 PluginManager::RegisterPlugin (GetPluginNameStatic(), 93 GetPluginDescriptionStatic(), 94 CreateInstance); 95} 96 97void 98SymbolFileDWARF::Terminate() 99{ 100 PluginManager::UnregisterPlugin (CreateInstance); 101 LogChannelDWARF::Initialize(); 102} 103 104 105const char * 106SymbolFileDWARF::GetPluginNameStatic() 107{ 108 return "symbol-file.dwarf2"; 109} 110 111const char * 112SymbolFileDWARF::GetPluginDescriptionStatic() 113{ 114 return "DWARF and DWARF3 debug symbol file reader."; 115} 116 117 118SymbolFile* 119SymbolFileDWARF::CreateInstance (ObjectFile* obj_file) 120{ 121 return new SymbolFileDWARF(obj_file); 122} 123 124TypeList * 125SymbolFileDWARF::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//---------------------------------------------------------------------- 137static const DWARFDebugInfoEntry * 138GetParentSymbolContextDIE(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 158SymbolFileDWARF::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 189SymbolFileDWARF::~SymbolFileDWARF() 190{ 191 if (m_is_external_ast_source) 192 m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource (); 193} 194 195static const ConstString & 196GetDWARFMachOSegmentName () 197{ 198 static ConstString g_dwarf_section_name ("__DWARF"); 199 return g_dwarf_section_name; 200} 201 202UniqueDWARFASTTypeMap & 203SymbolFileDWARF::GetUniqueDWARFASTTypeMap () 204{ 205 if (m_debug_map_symfile) 206 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap (); 207 return m_unique_ast_type_map; 208} 209 210ClangASTContext & 211SymbolFileDWARF::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 231void 232SymbolFileDWARF::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 249bool 250SymbolFileDWARF::SupportedVersion(uint16_t version) 251{ 252 return version == 2 || version == 3; 253} 254 255uint32_t 256SymbolFileDWARF::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 373const DataExtractor& 374SymbolFileDWARF::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 401const DataExtractor& 402SymbolFileDWARF::get_debug_abbrev_data() 403{ 404 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev); 405} 406 407const DataExtractor& 408SymbolFileDWARF::get_debug_frame_data() 409{ 410 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame); 411} 412 413const DataExtractor& 414SymbolFileDWARF::get_debug_info_data() 415{ 416 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info); 417} 418 419const DataExtractor& 420SymbolFileDWARF::get_debug_line_data() 421{ 422 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line); 423} 424 425const DataExtractor& 426SymbolFileDWARF::get_debug_loc_data() 427{ 428 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc); 429} 430 431const DataExtractor& 432SymbolFileDWARF::get_debug_ranges_data() 433{ 434 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges); 435} 436 437const DataExtractor& 438SymbolFileDWARF::get_debug_str_data() 439{ 440 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str); 441} 442 443 444DWARFDebugAbbrev* 445SymbolFileDWARF::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 460const DWARFDebugAbbrev* 461SymbolFileDWARF::DebugAbbrev() const 462{ 463 return m_abbr.get(); 464} 465 466DWARFDebugAranges* 467SymbolFileDWARF::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 495const DWARFDebugAranges* 496SymbolFileDWARF::DebugAranges() const 497{ 498 return m_aranges.get(); 499} 500 501 502DWARFDebugInfo* 503SymbolFileDWARF::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 520const DWARFDebugInfo* 521SymbolFileDWARF::DebugInfo() const 522{ 523 return m_info.get(); 524} 525 526DWARFCompileUnit* 527SymbolFileDWARF::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 536DWARFDebugRanges* 537SymbolFileDWARF::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 552const DWARFDebugRanges* 553SymbolFileDWARF::DebugRanges() const 554{ 555 return m_ranges.get(); 556} 557 558bool 559SymbolFileDWARF::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 600uint32_t 601SymbolFileDWARF::GetNumCompileUnits() 602{ 603 DWARFDebugInfo* info = DebugInfo(); 604 if (info) 605 return info->GetNumCompileUnits(); 606 return 0; 607} 608 609CompUnitSP 610SymbolFileDWARF::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 630static void 631AddRangesToBlock 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 648Function * 649SymbolFileDWARF::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 740size_t 741SymbolFileDWARF::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 765bool 766SymbolFileDWARF::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 787struct 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//---------------------------------------------------------------------- 803static void 804ParseDWARFLineTableCallback(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 965bool 966SymbolFileDWARF::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 993size_t 994SymbolFileDWARF::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 1110size_t 1111SymbolFileDWARF::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 1357clang::DeclContext* 1358SymbolFileDWARF::GetClangDeclContextForTypeUID (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 GetClangDeclContextForDIE (cu_sp.get(), die); 1367 } 1368 return NULL; 1369} 1370 1371Type* 1372SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid) 1373{ 1374 DWARFDebugInfo* debug_info = DebugInfo(); 1375 if (debug_info) 1376 { 1377 DWARFCompileUnitSP cu_sp; 1378 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp); 1379 if (type_die != NULL) 1380 { 1381 // We might be coming in in the middle of a type tree (a class 1382 // withing a class, an enum within a class), so parse any needed 1383 // parent DIEs before we get to this one... 1384 const DWARFDebugInfoEntry* parent_die = type_die->GetParent(); 1385 switch (parent_die->Tag()) 1386 { 1387 case DW_TAG_structure_type: 1388 case DW_TAG_union_type: 1389 case DW_TAG_class_type: 1390 ResolveType(cu_sp.get(), parent_die); 1391 break; 1392 } 1393 return ResolveType (cu_sp.get(), type_die); 1394 } 1395 } 1396 return NULL; 1397} 1398 1399// This function is used when SymbolFileDWARFDebugMap owns a bunch of 1400// SymbolFileDWARF objects to detect if this DWARF file is the one that 1401// can resolve a clang_type. 1402bool 1403SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type) 1404{ 1405 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type); 1406 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers); 1407 return die != NULL; 1408} 1409 1410 1411lldb::clang_type_t 1412SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type) 1413{ 1414 // We have a struct/union/class/enum that needs to be fully resolved. 1415 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type); 1416 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers); 1417 if (die == NULL) 1418 { 1419// if (m_debug_map_symfile) 1420// { 1421// Type *type = m_die_to_type[die]; 1422// if (type && type->GetSymbolFile() != this) 1423// return type->GetClangType(); 1424// } 1425 // We have already resolved this type... 1426 return clang_type; 1427 } 1428 // Once we start resolving this type, remove it from the forward declaration 1429 // map in case anyone child members or other types require this type to get resolved. 1430 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition 1431 // are done. 1432 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers); 1433 1434 1435 DWARFDebugInfo* debug_info = DebugInfo(); 1436 1437 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get(); 1438 Type *type = m_die_to_type.lookup (die); 1439 1440 const dw_tag_t tag = die->Tag(); 1441 1442 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n", 1443 die->GetOffset(), 1444 DW_TAG_value_to_name(tag), 1445 type->GetName().AsCString()); 1446 assert (clang_type); 1447 DWARFDebugInfoEntry::Attributes attributes; 1448 1449 ClangASTContext &ast = GetClangASTContext(); 1450 1451 switch (tag) 1452 { 1453 case DW_TAG_structure_type: 1454 case DW_TAG_union_type: 1455 case DW_TAG_class_type: 1456 ast.StartTagDeclarationDefinition (clang_type); 1457 if (die->HasChildren()) 1458 { 1459 LanguageType class_language = eLanguageTypeUnknown; 1460 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type); 1461 if (is_objc_class) 1462 class_language = eLanguageTypeObjC; 1463 1464 int tag_decl_kind = -1; 1465 AccessType default_accessibility = eAccessNone; 1466 if (tag == DW_TAG_structure_type) 1467 { 1468 tag_decl_kind = clang::TTK_Struct; 1469 default_accessibility = eAccessPublic; 1470 } 1471 else if (tag == DW_TAG_union_type) 1472 { 1473 tag_decl_kind = clang::TTK_Union; 1474 default_accessibility = eAccessPublic; 1475 } 1476 else if (tag == DW_TAG_class_type) 1477 { 1478 tag_decl_kind = clang::TTK_Class; 1479 default_accessibility = eAccessPrivate; 1480 } 1481 1482 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu)); 1483 std::vector<clang::CXXBaseSpecifier *> base_classes; 1484 std::vector<int> member_accessibilities; 1485 bool is_a_class = false; 1486 // Parse members and base classes first 1487 DWARFDIECollection member_function_dies; 1488 1489 ParseChildMembers (sc, 1490 curr_cu, 1491 die, 1492 clang_type, 1493 class_language, 1494 base_classes, 1495 member_accessibilities, 1496 member_function_dies, 1497 default_accessibility, 1498 is_a_class); 1499 1500 // Now parse any methods if there were any... 1501 size_t num_functions = member_function_dies.Size(); 1502 if (num_functions > 0) 1503 { 1504 for (size_t i=0; i<num_functions; ++i) 1505 { 1506 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i)); 1507 } 1508 } 1509 1510 if (class_language == eLanguageTypeObjC) 1511 { 1512 std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type)); 1513 if (!class_str.empty()) 1514 { 1515 1516 ConstString class_name (class_str.c_str()); 1517 std::vector<NameToDIE::Info> method_die_infos; 1518 if (m_objc_class_selectors_index.Find (class_name, method_die_infos)) 1519 { 1520 DWARFCompileUnit* method_cu = NULL; 1521 DWARFCompileUnit* prev_method_cu = NULL; 1522 const size_t num_objc_methods = method_die_infos.size(); 1523 for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu) 1524 { 1525 method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx); 1526 1527 if (method_cu != prev_method_cu) 1528 method_cu->ExtractDIEsIfNeeded (false); 1529 1530 DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx); 1531 1532 ResolveType (method_cu, method_die); 1533 } 1534 } 1535 } 1536 } 1537 1538 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we 1539 // need to tell the clang type it is actually a class. 1540 if (class_language != eLanguageTypeObjC) 1541 { 1542 if (is_a_class && tag_decl_kind != clang::TTK_Class) 1543 ast.SetTagTypeKind (clang_type, clang::TTK_Class); 1544 } 1545 1546 // Since DW_TAG_structure_type gets used for both classes 1547 // and structures, we may need to set any DW_TAG_member 1548 // fields to have a "private" access if none was specified. 1549 // When we parsed the child members we tracked that actual 1550 // accessibility value for each DW_TAG_member in the 1551 // "member_accessibilities" array. If the value for the 1552 // member is zero, then it was set to the "default_accessibility" 1553 // which for structs was "public". Below we correct this 1554 // by setting any fields to "private" that weren't correctly 1555 // set. 1556 if (is_a_class && !member_accessibilities.empty()) 1557 { 1558 // This is a class and all members that didn't have 1559 // their access specified are private. 1560 ast.SetDefaultAccessForRecordFields (clang_type, 1561 eAccessPrivate, 1562 &member_accessibilities.front(), 1563 member_accessibilities.size()); 1564 } 1565 1566 if (!base_classes.empty()) 1567 { 1568 ast.SetBaseClassesForClassType (clang_type, 1569 &base_classes.front(), 1570 base_classes.size()); 1571 1572 // Clang will copy each CXXBaseSpecifier in "base_classes" 1573 // so we have to free them all. 1574 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(), 1575 base_classes.size()); 1576 } 1577 1578 } 1579 ast.CompleteTagDeclarationDefinition (clang_type); 1580 return clang_type; 1581 1582 case DW_TAG_enumeration_type: 1583 ast.StartTagDeclarationDefinition (clang_type); 1584 if (die->HasChildren()) 1585 { 1586 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu)); 1587 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die); 1588 } 1589 ast.CompleteTagDeclarationDefinition (clang_type); 1590 return clang_type; 1591 1592 default: 1593 assert(false && "not a forward clang type decl!"); 1594 break; 1595 } 1596 return NULL; 1597} 1598 1599Type* 1600SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed) 1601{ 1602 if (type_die != NULL) 1603 { 1604 Type *type = m_die_to_type.lookup (type_die); 1605 if (type == NULL) 1606 type = GetTypeForDIE (curr_cu, type_die).get(); 1607 if (assert_not_being_parsed) 1608 assert (type != DIE_IS_BEING_PARSED); 1609 return type; 1610 } 1611 return NULL; 1612} 1613 1614CompileUnit* 1615SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx) 1616{ 1617 // Check if the symbol vendor already knows about this compile unit? 1618 if (curr_cu->GetUserData() == NULL) 1619 { 1620 // The symbol vendor doesn't know about this compile unit, we 1621 // need to parse and add it to the symbol vendor object. 1622 CompUnitSP dc_cu; 1623 ParseCompileUnit(curr_cu, dc_cu); 1624 if (dc_cu.get()) 1625 { 1626 // Figure out the compile unit index if we weren't given one 1627 if (cu_idx == UINT32_MAX) 1628 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx); 1629 1630 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx); 1631 1632 if (m_debug_map_symfile) 1633 m_debug_map_symfile->SetCompileUnit(this, dc_cu); 1634 } 1635 } 1636 return (CompileUnit*)curr_cu->GetUserData(); 1637} 1638 1639bool 1640SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc) 1641{ 1642 sc.Clear(); 1643 // Check if the symbol vendor already knows about this compile unit? 1644 sc.module_sp = m_obj_file->GetModule()->GetSP(); 1645 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX); 1646 1647 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get(); 1648 if (sc.function == NULL) 1649 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die); 1650 1651 return sc.function != NULL; 1652} 1653 1654uint32_t 1655SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 1656{ 1657 Timer scoped_timer(__PRETTY_FUNCTION__, 1658 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)", 1659 so_addr.GetSection(), 1660 so_addr.GetOffset(), 1661 resolve_scope); 1662 uint32_t resolved = 0; 1663 if (resolve_scope & ( eSymbolContextCompUnit | 1664 eSymbolContextFunction | 1665 eSymbolContextBlock | 1666 eSymbolContextLineEntry)) 1667 { 1668 lldb::addr_t file_vm_addr = so_addr.GetFileAddress(); 1669 1670 DWARFDebugAranges* debug_aranges = DebugAranges(); 1671 DWARFDebugInfo* debug_info = DebugInfo(); 1672 if (debug_aranges) 1673 { 1674 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr); 1675 if (cu_offset != DW_INVALID_OFFSET) 1676 { 1677 uint32_t cu_idx; 1678 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get(); 1679 if (curr_cu) 1680 { 1681 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx); 1682 assert(sc.comp_unit != NULL); 1683 resolved |= eSymbolContextCompUnit; 1684 1685 if (resolve_scope & eSymbolContextLineEntry) 1686 { 1687 LineTable *line_table = sc.comp_unit->GetLineTable(); 1688 if (line_table == NULL) 1689 { 1690 if (ParseCompileUnitLineTable(sc)) 1691 line_table = sc.comp_unit->GetLineTable(); 1692 } 1693 if (line_table != NULL) 1694 { 1695 if (so_addr.IsLinkedAddress()) 1696 { 1697 Address linked_addr (so_addr); 1698 linked_addr.ResolveLinkedAddress(); 1699 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry)) 1700 { 1701 resolved |= eSymbolContextLineEntry; 1702 } 1703 } 1704 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry)) 1705 { 1706 resolved |= eSymbolContextLineEntry; 1707 } 1708 } 1709 } 1710 1711 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 1712 { 1713 DWARFDebugInfoEntry *function_die = NULL; 1714 DWARFDebugInfoEntry *block_die = NULL; 1715 if (resolve_scope & eSymbolContextBlock) 1716 { 1717 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die); 1718 } 1719 else 1720 { 1721 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL); 1722 } 1723 1724 if (function_die != NULL) 1725 { 1726 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get(); 1727 if (sc.function == NULL) 1728 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die); 1729 } 1730 1731 if (sc.function != NULL) 1732 { 1733 resolved |= eSymbolContextFunction; 1734 1735 if (resolve_scope & eSymbolContextBlock) 1736 { 1737 Block& block = sc.function->GetBlock (true); 1738 1739 if (block_die != NULL) 1740 sc.block = block.FindBlockByID (block_die->GetOffset()); 1741 else 1742 sc.block = block.FindBlockByID (function_die->GetOffset()); 1743 if (sc.block) 1744 resolved |= eSymbolContextBlock; 1745 } 1746 } 1747 } 1748 } 1749 } 1750 } 1751 } 1752 return resolved; 1753} 1754 1755 1756 1757uint32_t 1758SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 1759{ 1760 const uint32_t prev_size = sc_list.GetSize(); 1761 if (resolve_scope & eSymbolContextCompUnit) 1762 { 1763 DWARFDebugInfo* debug_info = DebugInfo(); 1764 if (debug_info) 1765 { 1766 uint32_t cu_idx; 1767 DWARFCompileUnit* curr_cu = NULL; 1768 1769 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx) 1770 { 1771 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx); 1772 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0; 1773 if (check_inlines || file_spec_matches_cu_file_spec) 1774 { 1775 SymbolContext sc (m_obj_file->GetModule()); 1776 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx); 1777 assert(sc.comp_unit != NULL); 1778 1779 uint32_t file_idx = UINT32_MAX; 1780 1781 // If we are looking for inline functions only and we don't 1782 // find it in the support files, we are done. 1783 if (check_inlines) 1784 { 1785 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec); 1786 if (file_idx == UINT32_MAX) 1787 continue; 1788 } 1789 1790 if (line != 0) 1791 { 1792 LineTable *line_table = sc.comp_unit->GetLineTable(); 1793 1794 if (line_table != NULL && line != 0) 1795 { 1796 // We will have already looked up the file index if 1797 // we are searching for inline entries. 1798 if (!check_inlines) 1799 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec); 1800 1801 if (file_idx != UINT32_MAX) 1802 { 1803 uint32_t found_line; 1804 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry); 1805 found_line = sc.line_entry.line; 1806 1807 while (line_idx != UINT32_MAX) 1808 { 1809 sc.function = NULL; 1810 sc.block = NULL; 1811 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) 1812 { 1813 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress(); 1814 if (file_vm_addr != LLDB_INVALID_ADDRESS) 1815 { 1816 DWARFDebugInfoEntry *function_die = NULL; 1817 DWARFDebugInfoEntry *block_die = NULL; 1818 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL); 1819 1820 if (function_die != NULL) 1821 { 1822 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get(); 1823 if (sc.function == NULL) 1824 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die); 1825 } 1826 1827 if (sc.function != NULL) 1828 { 1829 Block& block = sc.function->GetBlock (true); 1830 1831 if (block_die != NULL) 1832 sc.block = block.FindBlockByID (block_die->GetOffset()); 1833 else 1834 sc.block = block.FindBlockByID (function_die->GetOffset()); 1835 } 1836 } 1837 } 1838 1839 sc_list.Append(sc); 1840 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry); 1841 } 1842 } 1843 } 1844 else if (file_spec_matches_cu_file_spec && !check_inlines) 1845 { 1846 // only append the context if we aren't looking for inline call sites 1847 // by file and line and if the file spec matches that of the compile unit 1848 sc_list.Append(sc); 1849 } 1850 } 1851 else if (file_spec_matches_cu_file_spec && !check_inlines) 1852 { 1853 // only append the context if we aren't looking for inline call sites 1854 // by file and line and if the file spec matches that of the compile unit 1855 sc_list.Append(sc); 1856 } 1857 1858 if (!check_inlines) 1859 break; 1860 } 1861 } 1862 } 1863 } 1864 return sc_list.GetSize() - prev_size; 1865} 1866 1867void 1868SymbolFileDWARF::Index () 1869{ 1870 if (m_indexed) 1871 return; 1872 m_indexed = true; 1873 Timer scoped_timer (__PRETTY_FUNCTION__, 1874 "SymbolFileDWARF::Index (%s)", 1875 GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 1876 1877 DWARFDebugInfo* debug_info = DebugInfo(); 1878 if (debug_info) 1879 { 1880 m_aranges.reset(new DWARFDebugAranges()); 1881 1882 uint32_t cu_idx = 0; 1883 const uint32_t num_compile_units = GetNumCompileUnits(); 1884 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) 1885 { 1886 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx); 1887 1888 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1; 1889 1890 curr_cu->Index (cu_idx, 1891 m_function_basename_index, 1892 m_function_fullname_index, 1893 m_function_method_index, 1894 m_function_selector_index, 1895 m_objc_class_selectors_index, 1896 m_global_index, 1897 m_type_index, 1898 m_namespace_index, 1899 DebugRanges(), 1900 m_aranges.get()); 1901 1902 // Keep memory down by clearing DIEs if this generate function 1903 // caused them to be parsed 1904 if (clear_dies) 1905 curr_cu->ClearDIEs (true); 1906 } 1907 1908 m_aranges->Sort(); 1909 1910#if defined (ENABLE_DEBUG_PRINTF) 1911 StreamFile s(stdout, false); 1912 s.Printf ("DWARF index for (%s) '%s/%s':", 1913 GetObjectFile()->GetModule()->GetArchitecture().AsCString(), 1914 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(), 1915 GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 1916 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s); 1917 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s); 1918 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s); 1919 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s); 1920 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s); 1921 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s); 1922 s.Printf("\nTypes:\n"); m_type_index.Dump (&s); 1923 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s); 1924#endif 1925 } 1926} 1927 1928uint32_t 1929SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables) 1930{ 1931 DWARFDebugInfo* info = DebugInfo(); 1932 if (info == NULL) 1933 return 0; 1934 1935 // If we aren't appending the results to this list, then clear the list 1936 if (!append) 1937 variables.Clear(); 1938 1939 // Remember how many variables are in the list before we search in case 1940 // we are appending the results to a variable list. 1941 const uint32_t original_size = variables.GetSize(); 1942 1943 // Index the DWARF if we haven't already 1944 if (!m_indexed) 1945 Index (); 1946 1947 SymbolContext sc; 1948 sc.module_sp = m_obj_file->GetModule()->GetSP(); 1949 assert (sc.module_sp); 1950 1951 DWARFCompileUnit* curr_cu = NULL; 1952 DWARFCompileUnit* prev_cu = NULL; 1953 const DWARFDebugInfoEntry* die = NULL; 1954 std::vector<NameToDIE::Info> die_info_array; 1955 const size_t num_matches = m_global_index.Find(name, die_info_array); 1956 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) 1957 { 1958 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); 1959 1960 if (curr_cu != prev_cu) 1961 curr_cu->ExtractDIEsIfNeeded (false); 1962 1963 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); 1964 1965 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX); 1966 assert(sc.comp_unit != NULL); 1967 1968 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables); 1969 1970 if (variables.GetSize() - original_size >= max_matches) 1971 break; 1972 } 1973 1974 // Return the number of variable that were appended to the list 1975 return variables.GetSize() - original_size; 1976} 1977 1978uint32_t 1979SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) 1980{ 1981 DWARFDebugInfo* info = DebugInfo(); 1982 if (info == NULL) 1983 return 0; 1984 1985 // If we aren't appending the results to this list, then clear the list 1986 if (!append) 1987 variables.Clear(); 1988 1989 // Remember how many variables are in the list before we search in case 1990 // we are appending the results to a variable list. 1991 const uint32_t original_size = variables.GetSize(); 1992 1993 // Index the DWARF if we haven't already 1994 if (!m_indexed) 1995 Index (); 1996 1997 SymbolContext sc; 1998 sc.module_sp = m_obj_file->GetModule()->GetSP(); 1999 assert (sc.module_sp); 2000 2001 DWARFCompileUnit* curr_cu = NULL; 2002 DWARFCompileUnit* prev_cu = NULL; 2003 const DWARFDebugInfoEntry* die = NULL; 2004 std::vector<NameToDIE::Info> die_info_array; 2005 const size_t num_matches = m_global_index.Find(regex, die_info_array); 2006 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) 2007 { 2008 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); 2009 2010 if (curr_cu != prev_cu) 2011 curr_cu->ExtractDIEsIfNeeded (false); 2012 2013 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); 2014 2015 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX); 2016 assert(sc.comp_unit != NULL); 2017 2018 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables); 2019 2020 if (variables.GetSize() - original_size >= max_matches) 2021 break; 2022 } 2023 2024 // Return the number of variable that were appended to the list 2025 return variables.GetSize() - original_size; 2026} 2027 2028 2029void 2030SymbolFileDWARF::FindFunctions 2031( 2032 const ConstString &name, 2033 const NameToDIE &name_to_die, 2034 SymbolContextList& sc_list 2035) 2036{ 2037 DWARFDebugInfo* info = DebugInfo(); 2038 if (info == NULL) 2039 return; 2040 2041 SymbolContext sc; 2042 sc.module_sp = m_obj_file->GetModule()->GetSP(); 2043 assert (sc.module_sp); 2044 2045 DWARFCompileUnit* curr_cu = NULL; 2046 DWARFCompileUnit* prev_cu = NULL; 2047 const DWARFDebugInfoEntry* die = NULL; 2048 std::vector<NameToDIE::Info> die_info_array; 2049 const size_t num_matches = name_to_die.Find (name, die_info_array); 2050 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) 2051 { 2052 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); 2053 2054 if (curr_cu != prev_cu) 2055 curr_cu->ExtractDIEsIfNeeded (false); 2056 2057 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); 2058 2059 const DWARFDebugInfoEntry* inlined_die = NULL; 2060 if (die->Tag() == DW_TAG_inlined_subroutine) 2061 { 2062 inlined_die = die; 2063 2064 while ((die = die->GetParent()) != NULL) 2065 { 2066 if (die->Tag() == DW_TAG_subprogram) 2067 break; 2068 } 2069 } 2070 assert (die->Tag() == DW_TAG_subprogram); 2071 if (GetFunction (curr_cu, die, sc)) 2072 { 2073 Address addr; 2074 // Parse all blocks if needed 2075 if (inlined_die) 2076 { 2077 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset()); 2078 assert (sc.block != NULL); 2079 if (sc.block->GetStartAddress (addr) == false) 2080 addr.Clear(); 2081 } 2082 else 2083 { 2084 sc.block = NULL; 2085 addr = sc.function->GetAddressRange().GetBaseAddress(); 2086 } 2087 2088 if (addr.IsValid()) 2089 { 2090 2091 // We found the function, so we should find the line table 2092 // and line table entry as well 2093 LineTable *line_table = sc.comp_unit->GetLineTable(); 2094 if (line_table == NULL) 2095 { 2096 if (ParseCompileUnitLineTable(sc)) 2097 line_table = sc.comp_unit->GetLineTable(); 2098 } 2099 if (line_table != NULL) 2100 line_table->FindLineEntryByAddress (addr, sc.line_entry); 2101 2102 sc_list.Append(sc); 2103 } 2104 } 2105 } 2106} 2107 2108 2109void 2110SymbolFileDWARF::FindFunctions 2111( 2112 const RegularExpression ®ex, 2113 const NameToDIE &name_to_die, 2114 SymbolContextList& sc_list 2115) 2116{ 2117 DWARFDebugInfo* info = DebugInfo(); 2118 if (info == NULL) 2119 return; 2120 2121 SymbolContext sc; 2122 sc.module_sp = m_obj_file->GetModule()->GetSP(); 2123 assert (sc.module_sp); 2124 2125 DWARFCompileUnit* curr_cu = NULL; 2126 DWARFCompileUnit* prev_cu = NULL; 2127 const DWARFDebugInfoEntry* die = NULL; 2128 std::vector<NameToDIE::Info> die_info_array; 2129 const size_t num_matches = name_to_die.Find(regex, die_info_array); 2130 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) 2131 { 2132 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); 2133 2134 if (curr_cu != prev_cu) 2135 curr_cu->ExtractDIEsIfNeeded (false); 2136 2137 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); 2138 2139 const DWARFDebugInfoEntry* inlined_die = NULL; 2140 if (die->Tag() == DW_TAG_inlined_subroutine) 2141 { 2142 inlined_die = die; 2143 2144 while ((die = die->GetParent()) != NULL) 2145 { 2146 if (die->Tag() == DW_TAG_subprogram) 2147 break; 2148 } 2149 } 2150 assert (die->Tag() == DW_TAG_subprogram); 2151 if (GetFunction (curr_cu, die, sc)) 2152 { 2153 Address addr; 2154 // Parse all blocks if needed 2155 if (inlined_die) 2156 { 2157 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset()); 2158 assert (sc.block != NULL); 2159 if (sc.block->GetStartAddress (addr) == false) 2160 addr.Clear(); 2161 } 2162 else 2163 { 2164 sc.block = NULL; 2165 addr = sc.function->GetAddressRange().GetBaseAddress(); 2166 } 2167 2168 if (addr.IsValid()) 2169 { 2170 2171 // We found the function, so we should find the line table 2172 // and line table entry as well 2173 LineTable *line_table = sc.comp_unit->GetLineTable(); 2174 if (line_table == NULL) 2175 { 2176 if (ParseCompileUnitLineTable(sc)) 2177 line_table = sc.comp_unit->GetLineTable(); 2178 } 2179 if (line_table != NULL) 2180 line_table->FindLineEntryByAddress (addr, sc.line_entry); 2181 2182 sc_list.Append(sc); 2183 } 2184 } 2185 } 2186} 2187 2188uint32_t 2189SymbolFileDWARF::FindFunctions 2190( 2191 const ConstString &name, 2192 uint32_t name_type_mask, 2193 bool append, 2194 SymbolContextList& sc_list 2195) 2196{ 2197 Timer scoped_timer (__PRETTY_FUNCTION__, 2198 "SymbolFileDWARF::FindFunctions (name = '%s')", 2199 name.AsCString()); 2200 2201 // If we aren't appending the results to this list, then clear the list 2202 if (!append) 2203 sc_list.Clear(); 2204 2205 // Remember how many sc_list are in the list before we search in case 2206 // we are appending the results to a variable list. 2207 uint32_t original_size = sc_list.GetSize(); 2208 2209 // Index the DWARF if we haven't already 2210 if (!m_indexed) 2211 Index (); 2212 2213 if (name_type_mask & eFunctionNameTypeBase) 2214 FindFunctions (name, m_function_basename_index, sc_list); 2215 2216 if (name_type_mask & eFunctionNameTypeFull) 2217 FindFunctions (name, m_function_fullname_index, sc_list); 2218 2219 if (name_type_mask & eFunctionNameTypeMethod) 2220 FindFunctions (name, m_function_method_index, sc_list); 2221 2222 if (name_type_mask & eFunctionNameTypeSelector) 2223 FindFunctions (name, m_function_selector_index, sc_list); 2224 2225 // Return the number of variable that were appended to the list 2226 return sc_list.GetSize() - original_size; 2227} 2228 2229 2230uint32_t 2231SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list) 2232{ 2233 Timer scoped_timer (__PRETTY_FUNCTION__, 2234 "SymbolFileDWARF::FindFunctions (regex = '%s')", 2235 regex.GetText()); 2236 2237 // If we aren't appending the results to this list, then clear the list 2238 if (!append) 2239 sc_list.Clear(); 2240 2241 // Remember how many sc_list are in the list before we search in case 2242 // we are appending the results to a variable list. 2243 uint32_t original_size = sc_list.GetSize(); 2244 2245 // Index the DWARF if we haven't already 2246 if (!m_indexed) 2247 Index (); 2248 2249 FindFunctions (regex, m_function_basename_index, sc_list); 2250 2251 FindFunctions (regex, m_function_fullname_index, sc_list); 2252 2253 // Return the number of variable that were appended to the list 2254 return sc_list.GetSize() - original_size; 2255} 2256void 2257SymbolFileDWARF::ReportError (const char *format, ...) 2258{ 2259 ::fprintf (stderr, 2260 "error: %s/%s ", 2261 m_obj_file->GetFileSpec().GetDirectory().GetCString(), 2262 m_obj_file->GetFileSpec().GetFilename().GetCString()); 2263 2264 va_list args; 2265 va_start (args, format); 2266 vfprintf (stderr, format, args); 2267 va_end (args); 2268} 2269 2270uint32_t 2271SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types) 2272{ 2273 DWARFDebugInfo* info = DebugInfo(); 2274 if (info == NULL) 2275 return 0; 2276 2277 // If we aren't appending the results to this list, then clear the list 2278 if (!append) 2279 types.Clear(); 2280 2281 // Index if we already haven't to make sure the compile units 2282 // get indexed and make their global DIE index list 2283 if (!m_indexed) 2284 Index (); 2285 2286 const uint32_t initial_types_size = types.GetSize(); 2287 DWARFCompileUnit* curr_cu = NULL; 2288 DWARFCompileUnit* prev_cu = NULL; 2289 const DWARFDebugInfoEntry* die = NULL; 2290 std::vector<NameToDIE::Info> die_info_array; 2291 const size_t num_matches = m_type_index.Find (name, die_info_array); 2292 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) 2293 { 2294 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); 2295 2296 if (curr_cu != prev_cu) 2297 curr_cu->ExtractDIEsIfNeeded (false); 2298 2299 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); 2300 2301 Type *matching_type = ResolveType (curr_cu, die); 2302 if (matching_type) 2303 { 2304 // We found a type pointer, now find the shared pointer form our type list 2305 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID())); 2306 if (type_sp) 2307 { 2308 types.InsertUnique (type_sp); 2309 if (types.GetSize() >= max_matches) 2310 break; 2311 } 2312 else 2313 { 2314 fprintf (stderr, "error: can't find shared pointer for type 0x%8.8x.\n", matching_type->GetID()); 2315 } 2316 } 2317 } 2318 return types.GetSize() - initial_types_size; 2319} 2320 2321 2322ClangNamespaceDecl 2323SymbolFileDWARF::FindNamespace (const SymbolContext& sc, 2324 const ConstString &name) 2325{ 2326 ClangNamespaceDecl namespace_decl; 2327 DWARFDebugInfo* info = DebugInfo(); 2328 if (info) 2329 { 2330 // Index if we already haven't to make sure the compile units 2331 // get indexed and make their global DIE index list 2332 if (!m_indexed) 2333 Index (); 2334 2335 DWARFCompileUnit* curr_cu = NULL; 2336 DWARFCompileUnit* prev_cu = NULL; 2337 const DWARFDebugInfoEntry* die = NULL; 2338 std::vector<NameToDIE::Info> die_info_array; 2339 const size_t num_matches = m_namespace_index.Find (name, die_info_array); 2340 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu) 2341 { 2342 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); 2343 2344 if (curr_cu != prev_cu) 2345 curr_cu->ExtractDIEsIfNeeded (false); 2346 2347 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); 2348 2349 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (curr_cu, die); 2350 if (clang_namespace_decl) 2351 { 2352 namespace_decl.SetASTContext (GetClangASTContext().getASTContext()); 2353 namespace_decl.SetNamespaceDecl (clang_namespace_decl); 2354 } 2355 } 2356 } 2357 return namespace_decl; 2358} 2359 2360uint32_t 2361SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types) 2362{ 2363 // Remember how many sc_list are in the list before we search in case 2364 // we are appending the results to a variable list. 2365 uint32_t original_size = types.GetSize(); 2366 2367 const uint32_t num_die_offsets = die_offsets.size(); 2368 // Parse all of the types we found from the pubtypes matches 2369 uint32_t i; 2370 uint32_t num_matches = 0; 2371 for (i = 0; i < num_die_offsets; ++i) 2372 { 2373 Type *matching_type = ResolveTypeUID (die_offsets[i]); 2374 if (matching_type) 2375 { 2376 // We found a type pointer, now find the shared pointer form our type list 2377 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID())); 2378 assert (type_sp.get() != NULL); 2379 types.InsertUnique (type_sp); 2380 ++num_matches; 2381 if (num_matches >= max_matches) 2382 break; 2383 } 2384 } 2385 2386 // Return the number of variable that were appended to the list 2387 return types.GetSize() - original_size; 2388} 2389 2390 2391size_t 2392SymbolFileDWARF::ParseChildParameters 2393( 2394 const SymbolContext& sc, 2395 TypeSP& type_sp, 2396 DWARFCompileUnit* dwarf_cu, 2397 const DWARFDebugInfoEntry *parent_die, 2398 bool skip_artificial, 2399 bool &is_static, 2400 TypeList* type_list, 2401 std::vector<clang_type_t>& function_param_types, 2402 std::vector<clang::ParmVarDecl*>& function_param_decls, 2403 unsigned &type_quals 2404) 2405{ 2406 if (parent_die == NULL) 2407 return 0; 2408 2409 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 2410 2411 size_t arg_idx = 0; 2412 const DWARFDebugInfoEntry *die; 2413 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2414 { 2415 dw_tag_t tag = die->Tag(); 2416 switch (tag) 2417 { 2418 case DW_TAG_formal_parameter: 2419 { 2420 DWARFDebugInfoEntry::Attributes attributes; 2421 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 2422 if (num_attributes > 0) 2423 { 2424 const char *name = NULL; 2425 Declaration decl; 2426 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET; 2427 bool is_artificial = false; 2428 // one of None, Auto, Register, Extern, Static, PrivateExtern 2429 2430 clang::StorageClass storage = clang::SC_None; 2431 uint32_t i; 2432 for (i=0; i<num_attributes; ++i) 2433 { 2434 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2435 DWARFFormValue form_value; 2436 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2437 { 2438 switch (attr) 2439 { 2440 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2441 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2442 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2443 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 2444 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break; 2445 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break; 2446 case DW_AT_location: 2447 // if (form_value.BlockData()) 2448 // { 2449 // const DataExtractor& debug_info_data = debug_info(); 2450 // uint32_t block_length = form_value.Unsigned(); 2451 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length); 2452 // } 2453 // else 2454 // { 2455 // } 2456 // break; 2457 case DW_AT_const_value: 2458 case DW_AT_default_value: 2459 case DW_AT_description: 2460 case DW_AT_endianity: 2461 case DW_AT_is_optional: 2462 case DW_AT_segment: 2463 case DW_AT_variable_parameter: 2464 default: 2465 case DW_AT_abstract_origin: 2466 case DW_AT_sibling: 2467 break; 2468 } 2469 } 2470 } 2471 2472 bool skip = false; 2473 if (skip_artificial) 2474 { 2475 if (is_artificial) 2476 { 2477 // In order to determine if a C++ member function is 2478 // "const" we have to look at the const-ness of "this"... 2479 // Ugly, but that 2480 if (arg_idx == 0) 2481 { 2482 const DWARFDebugInfoEntry *grandparent_die = parent_die->GetParent(); 2483 if (grandparent_die && (grandparent_die->Tag() == DW_TAG_structure_type || 2484 grandparent_die->Tag() == DW_TAG_class_type)) 2485 { 2486 LanguageType language = sc.comp_unit->GetLanguage(); 2487 if (language == eLanguageTypeObjC_plus_plus || language == eLanguageTypeC_plus_plus) 2488 { 2489 // Often times compilers omit the "this" name for the 2490 // specification DIEs, so we can't rely upon the name 2491 // being in the formal parameter DIE... 2492 if (name == NULL || ::strcmp(name, "this")==0) 2493 { 2494 Type *this_type = ResolveTypeUID (param_type_die_offset); 2495 if (this_type) 2496 { 2497 uint32_t encoding_mask = this_type->GetEncodingMask(); 2498 if (encoding_mask & Type::eEncodingIsPointerUID) 2499 { 2500 is_static = false; 2501 2502 if (encoding_mask & (1u << Type::eEncodingIsConstUID)) 2503 type_quals |= clang::Qualifiers::Const; 2504 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID)) 2505 type_quals |= clang::Qualifiers::Volatile; 2506 } 2507 } 2508 } 2509 } 2510 } 2511 } 2512 skip = true; 2513 } 2514 else 2515 { 2516 2517 // HACK: Objective C formal parameters "self" and "_cmd" 2518 // are not marked as artificial in the DWARF... 2519 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX); 2520 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus)) 2521 { 2522 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0)) 2523 skip = true; 2524 } 2525 } 2526 } 2527 2528 if (!skip) 2529 { 2530 Type *type = ResolveTypeUID(param_type_die_offset); 2531 if (type) 2532 { 2533 function_param_types.push_back (type->GetClangForwardType()); 2534 2535 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage); 2536 assert(param_var_decl); 2537 function_param_decls.push_back(param_var_decl); 2538 } 2539 } 2540 } 2541 arg_idx++; 2542 } 2543 break; 2544 2545 default: 2546 break; 2547 } 2548 } 2549 return arg_idx; 2550} 2551 2552size_t 2553SymbolFileDWARF::ParseChildEnumerators 2554( 2555 const SymbolContext& sc, 2556 clang_type_t enumerator_clang_type, 2557 uint32_t enumerator_byte_size, 2558 DWARFCompileUnit* dwarf_cu, 2559 const DWARFDebugInfoEntry *parent_die 2560) 2561{ 2562 if (parent_die == NULL) 2563 return 0; 2564 2565 size_t enumerators_added = 0; 2566 const DWARFDebugInfoEntry *die; 2567 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 2568 2569 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2570 { 2571 const dw_tag_t tag = die->Tag(); 2572 if (tag == DW_TAG_enumerator) 2573 { 2574 DWARFDebugInfoEntry::Attributes attributes; 2575 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 2576 if (num_child_attributes > 0) 2577 { 2578 const char *name = NULL; 2579 bool got_value = false; 2580 int64_t enum_value = 0; 2581 Declaration decl; 2582 2583 uint32_t i; 2584 for (i=0; i<num_child_attributes; ++i) 2585 { 2586 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2587 DWARFFormValue form_value; 2588 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2589 { 2590 switch (attr) 2591 { 2592 case DW_AT_const_value: 2593 got_value = true; 2594 enum_value = form_value.Unsigned(); 2595 break; 2596 2597 case DW_AT_name: 2598 name = form_value.AsCString(&get_debug_str_data()); 2599 break; 2600 2601 case DW_AT_description: 2602 default: 2603 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 2604 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 2605 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 2606 case DW_AT_sibling: 2607 break; 2608 } 2609 } 2610 } 2611 2612 if (name && name[0] && got_value) 2613 { 2614 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type, 2615 enumerator_clang_type, 2616 decl, 2617 name, 2618 enum_value, 2619 enumerator_byte_size * 8); 2620 ++enumerators_added; 2621 } 2622 } 2623 } 2624 } 2625 return enumerators_added; 2626} 2627 2628void 2629SymbolFileDWARF::ParseChildArrayInfo 2630( 2631 const SymbolContext& sc, 2632 DWARFCompileUnit* dwarf_cu, 2633 const DWARFDebugInfoEntry *parent_die, 2634 int64_t& first_index, 2635 std::vector<uint64_t>& element_orders, 2636 uint32_t& byte_stride, 2637 uint32_t& bit_stride 2638) 2639{ 2640 if (parent_die == NULL) 2641 return; 2642 2643 const DWARFDebugInfoEntry *die; 2644 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize()); 2645 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling()) 2646 { 2647 const dw_tag_t tag = die->Tag(); 2648 switch (tag) 2649 { 2650 case DW_TAG_enumerator: 2651 { 2652 DWARFDebugInfoEntry::Attributes attributes; 2653 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 2654 if (num_child_attributes > 0) 2655 { 2656 const char *name = NULL; 2657 bool got_value = false; 2658 int64_t enum_value = 0; 2659 2660 uint32_t i; 2661 for (i=0; i<num_child_attributes; ++i) 2662 { 2663 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2664 DWARFFormValue form_value; 2665 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2666 { 2667 switch (attr) 2668 { 2669 case DW_AT_const_value: 2670 got_value = true; 2671 enum_value = form_value.Unsigned(); 2672 break; 2673 2674 case DW_AT_name: 2675 name = form_value.AsCString(&get_debug_str_data()); 2676 break; 2677 2678 case DW_AT_description: 2679 default: 2680 case DW_AT_decl_file: 2681 case DW_AT_decl_line: 2682 case DW_AT_decl_column: 2683 case DW_AT_sibling: 2684 break; 2685 } 2686 } 2687 } 2688 } 2689 } 2690 break; 2691 2692 case DW_TAG_subrange_type: 2693 { 2694 DWARFDebugInfoEntry::Attributes attributes; 2695 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes); 2696 if (num_child_attributes > 0) 2697 { 2698 const char *name = NULL; 2699 bool got_value = false; 2700 uint64_t byte_size = 0; 2701 int64_t enum_value = 0; 2702 uint64_t num_elements = 0; 2703 uint64_t lower_bound = 0; 2704 uint64_t upper_bound = 0; 2705 uint32_t i; 2706 for (i=0; i<num_child_attributes; ++i) 2707 { 2708 const dw_attr_t attr = attributes.AttributeAtIndex(i); 2709 DWARFFormValue form_value; 2710 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 2711 { 2712 switch (attr) 2713 { 2714 case DW_AT_const_value: 2715 got_value = true; 2716 enum_value = form_value.Unsigned(); 2717 break; 2718 2719 case DW_AT_name: 2720 name = form_value.AsCString(&get_debug_str_data()); 2721 break; 2722 2723 case DW_AT_count: 2724 num_elements = form_value.Unsigned(); 2725 break; 2726 2727 case DW_AT_bit_stride: 2728 bit_stride = form_value.Unsigned(); 2729 break; 2730 2731 case DW_AT_byte_stride: 2732 byte_stride = form_value.Unsigned(); 2733 break; 2734 2735 case DW_AT_byte_size: 2736 byte_size = form_value.Unsigned(); 2737 break; 2738 2739 case DW_AT_lower_bound: 2740 lower_bound = form_value.Unsigned(); 2741 break; 2742 2743 case DW_AT_upper_bound: 2744 upper_bound = form_value.Unsigned(); 2745 break; 2746 2747 default: 2748 case DW_AT_abstract_origin: 2749 case DW_AT_accessibility: 2750 case DW_AT_allocated: 2751 case DW_AT_associated: 2752 case DW_AT_data_location: 2753 case DW_AT_declaration: 2754 case DW_AT_description: 2755 case DW_AT_sibling: 2756 case DW_AT_threads_scaled: 2757 case DW_AT_type: 2758 case DW_AT_visibility: 2759 break; 2760 } 2761 } 2762 } 2763 2764 if (upper_bound > lower_bound) 2765 num_elements = upper_bound - lower_bound + 1; 2766 2767 if (num_elements > 0) 2768 element_orders.push_back (num_elements); 2769 } 2770 } 2771 break; 2772 } 2773 } 2774} 2775 2776TypeSP 2777SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die) 2778{ 2779 TypeSP type_sp; 2780 if (die != NULL) 2781 { 2782 assert(curr_cu != NULL); 2783 Type *type_ptr = m_die_to_type.lookup (die); 2784 if (type_ptr == NULL) 2785 { 2786 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu); 2787 assert (lldb_cu); 2788 SymbolContext sc(lldb_cu); 2789 type_sp = ParseType(sc, curr_cu, die, NULL); 2790 } 2791 else if (type_ptr != DIE_IS_BEING_PARSED) 2792 { 2793 // Grab the existing type from the master types lists 2794 type_sp = GetTypeList()->FindType(type_ptr->GetID()); 2795 } 2796 2797 } 2798 return type_sp; 2799} 2800 2801clang::DeclContext * 2802SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset) 2803{ 2804 if (die_offset != DW_INVALID_OFFSET) 2805 { 2806 DWARFCompileUnitSP cu_sp; 2807 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp); 2808 return GetClangDeclContextForDIE (cu_sp.get(), die); 2809 } 2810 return NULL; 2811} 2812 2813 2814clang::NamespaceDecl * 2815SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die) 2816{ 2817 if (die->Tag() == DW_TAG_namespace) 2818 { 2819 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL); 2820 if (namespace_name) 2821 { 2822 Declaration decl; // TODO: fill in the decl object 2823 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent())); 2824 if (namespace_decl) 2825 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die); 2826 return namespace_decl; 2827 } 2828 } 2829 return NULL; 2830} 2831 2832clang::DeclContext * 2833SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die) 2834{ 2835 if (m_clang_tu_decl == NULL) 2836 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl(); 2837 2838 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x )\n", die->GetOffset()); 2839 const DWARFDebugInfoEntry * const decl_die = die; 2840 clang::DeclContext *decl_ctx = NULL; 2841 2842 while (die != NULL) 2843 { 2844 // If this is the original DIE that we are searching for a declaration 2845 // for, then don't look in the cache as we don't want our own decl 2846 // context to be our decl context... 2847 if (decl_die != die) 2848 { 2849 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die); 2850 if (pos != m_die_to_decl_ctx.end()) 2851 { 2852 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); 2853 return pos->second; 2854 } 2855 2856 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) checking parent 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); 2857 2858 switch (die->Tag()) 2859 { 2860 case DW_TAG_namespace: 2861 { 2862 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL); 2863 if (namespace_name) 2864 { 2865 Declaration decl; // TODO: fill in the decl object 2866 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die)); 2867 if (namespace_decl) 2868 { 2869 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); 2870 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die); 2871 } 2872 return namespace_decl; 2873 } 2874 } 2875 break; 2876 2877 case DW_TAG_structure_type: 2878 case DW_TAG_union_type: 2879 case DW_TAG_class_type: 2880 { 2881 Type* type = ResolveType (curr_cu, die); 2882 pos = m_die_to_decl_ctx.find(die); 2883 if (pos != m_die_to_decl_ctx.end()) 2884 { 2885 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); 2886 return pos->second; 2887 } 2888 else 2889 { 2890 if (type) 2891 { 2892 decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ()); 2893 if (decl_ctx) 2894 return decl_ctx; 2895 } 2896 } 2897 } 2898 break; 2899 2900 default: 2901 break; 2902 } 2903 } 2904 2905 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET); 2906 if (die_offset != DW_INVALID_OFFSET) 2907 { 2908 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_specification 0x%8.8x\n", decl_die->GetOffset(), die_offset); 2909 decl_ctx = GetClangDeclContextForDIEOffset (die_offset); 2910 if (decl_ctx != m_clang_tu_decl) 2911 return decl_ctx; 2912 } 2913 2914 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET); 2915 if (die_offset != DW_INVALID_OFFSET) 2916 { 2917 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_abstract_origin 0x%8.8x\n", decl_die->GetOffset(), die_offset); 2918 decl_ctx = GetClangDeclContextForDIEOffset (die_offset); 2919 if (decl_ctx != m_clang_tu_decl) 2920 return decl_ctx; 2921 } 2922 2923 die = die->GetParent(); 2924 } 2925 // Right now we have only one translation unit per module... 2926 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), curr_cu->GetFirstDIEOffset()); 2927 return m_clang_tu_decl; 2928} 2929 2930// This function can be used when a DIE is found that is a forward declaration 2931// DIE and we want to try and find a type that has the complete definition. 2932TypeSP 2933SymbolFileDWARF::FindDefinitionTypeForDIE ( 2934 DWARFCompileUnit* cu, 2935 const DWARFDebugInfoEntry *die, 2936 const ConstString &type_name 2937) 2938{ 2939 TypeSP type_sp; 2940 2941 if (cu == NULL || die == NULL || !type_name) 2942 return type_sp; 2943 2944 if (!m_indexed) 2945 Index (); 2946 2947 const dw_tag_t type_tag = die->Tag(); 2948 std::vector<NameToDIE::Info> die_info_array; 2949 const size_t num_matches = m_type_index.Find (type_name, die_info_array); 2950 if (num_matches > 0) 2951 { 2952 DWARFCompileUnit* type_cu = NULL; 2953 DWARFCompileUnit* curr_cu = cu; 2954 DWARFDebugInfo *info = DebugInfo(); 2955 for (size_t i=0; i<num_matches; ++i) 2956 { 2957 type_cu = info->GetCompileUnitAtIndex (die_info_array[i].cu_idx); 2958 2959 if (type_cu != curr_cu) 2960 { 2961 type_cu->ExtractDIEsIfNeeded (false); 2962 curr_cu = type_cu; 2963 } 2964 2965 DWARFDebugInfoEntry *type_die = type_cu->GetDIEAtIndexUnchecked (die_info_array[i].die_idx); 2966 2967 if (type_die != die && type_die->Tag() == type_tag) 2968 { 2969 // Hold off on comparing parent DIE tags until 2970 // we know what happens with stuff in namespaces 2971 // for gcc and clang... 2972 //DWARFDebugInfoEntry *parent_die = die->GetParent(); 2973 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent(); 2974 //if (parent_die->Tag() == parent_type_die->Tag()) 2975 { 2976 Type *resolved_type = ResolveType (type_cu, type_die, false); 2977 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED) 2978 { 2979 DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n", 2980 die->GetOffset(), 2981 curr_cu->GetOffset(), 2982 m_obj_file->GetFileSpec().GetFilename().AsCString(), 2983 type_die->GetOffset(), 2984 type_cu->GetOffset()); 2985 2986 m_die_to_type[die] = resolved_type; 2987 type_sp = GetTypeList()->FindType(resolved_type->GetID()); 2988 if (!type_sp) 2989 { 2990 DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset()); 2991 } 2992 break; 2993 } 2994 } 2995 } 2996 } 2997 } 2998 return type_sp; 2999} 3000 3001TypeSP 3002SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr) 3003{ 3004 TypeSP type_sp; 3005 3006 if (type_is_new_ptr) 3007 *type_is_new_ptr = false; 3008 3009 AccessType accessibility = eAccessNone; 3010 if (die != NULL) 3011 { 3012 Type *type_ptr = m_die_to_type.lookup (die); 3013 TypeList* type_list = GetTypeList(); 3014 if (type_ptr == NULL) 3015 { 3016 ClangASTContext &ast = GetClangASTContext(); 3017 if (type_is_new_ptr) 3018 *type_is_new_ptr = true; 3019 3020 const dw_tag_t tag = die->Tag(); 3021 3022 bool is_forward_declaration = false; 3023 DWARFDebugInfoEntry::Attributes attributes; 3024 const char *type_name_cstr = NULL; 3025 ConstString type_name_const_str; 3026 Type::ResolveState resolve_state = Type::eResolveStateUnresolved; 3027 size_t byte_size = 0; 3028 bool byte_size_valid = false; 3029 Declaration decl; 3030 3031 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID; 3032 clang_type_t clang_type = NULL; 3033 3034 dw_attr_t attr; 3035 3036 switch (tag) 3037 { 3038 case DW_TAG_base_type: 3039 case DW_TAG_pointer_type: 3040 case DW_TAG_reference_type: 3041 case DW_TAG_typedef: 3042 case DW_TAG_const_type: 3043 case DW_TAG_restrict_type: 3044 case DW_TAG_volatile_type: 3045 { 3046 // Set a bit that lets us know that we are currently parsing this 3047 m_die_to_type[die] = DIE_IS_BEING_PARSED; 3048 3049 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3050 uint32_t encoding = 0; 3051 lldb::user_id_t encoding_uid = LLDB_INVALID_UID; 3052 3053 if (num_attributes > 0) 3054 { 3055 uint32_t i; 3056 for (i=0; i<num_attributes; ++i) 3057 { 3058 attr = attributes.AttributeAtIndex(i); 3059 DWARFFormValue form_value; 3060 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3061 { 3062 switch (attr) 3063 { 3064 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3065 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3066 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3067 case DW_AT_name: 3068 3069 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3070 // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't 3071 // include the "&"... 3072 if (tag == DW_TAG_reference_type) 3073 { 3074 if (strchr (type_name_cstr, '&') == NULL) 3075 type_name_cstr = NULL; 3076 } 3077 if (type_name_cstr) 3078 type_name_const_str.SetCString(type_name_cstr); 3079 break; 3080 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break; 3081 case DW_AT_encoding: encoding = form_value.Unsigned(); break; 3082 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 3083 default: 3084 case DW_AT_sibling: 3085 break; 3086 } 3087 } 3088 } 3089 } 3090 3091 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); 3092 3093 switch (tag) 3094 { 3095 default: 3096 break; 3097 3098 case DW_TAG_base_type: 3099 resolve_state = Type::eResolveStateFull; 3100 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, 3101 encoding, 3102 byte_size * 8); 3103 break; 3104 3105 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break; 3106 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break; 3107 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break; 3108 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break; 3109 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break; 3110 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break; 3111 } 3112 3113 if (type_name_cstr != NULL && sc.comp_unit != NULL && 3114 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus)) 3115 { 3116 static ConstString g_objc_type_name_id("id"); 3117 static ConstString g_objc_type_name_Class("Class"); 3118 static ConstString g_objc_type_name_selector("SEL"); 3119 3120 if (type_name_const_str == g_objc_type_name_id) 3121 { 3122 clang_type = ast.GetBuiltInType_objc_id(); 3123 resolve_state = Type::eResolveStateFull; 3124 3125 } 3126 else if (type_name_const_str == g_objc_type_name_Class) 3127 { 3128 clang_type = ast.GetBuiltInType_objc_Class(); 3129 resolve_state = Type::eResolveStateFull; 3130 } 3131 else if (type_name_const_str == g_objc_type_name_selector) 3132 { 3133 clang_type = ast.GetBuiltInType_objc_selector(); 3134 resolve_state = Type::eResolveStateFull; 3135 } 3136 } 3137 3138 type_sp.reset( new Type (die->GetOffset(), 3139 this, 3140 type_name_const_str, 3141 byte_size, 3142 NULL, 3143 encoding_uid, 3144 encoding_data_type, 3145 &decl, 3146 clang_type, 3147 resolve_state)); 3148 3149 m_die_to_type[die] = type_sp.get(); 3150 3151// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false); 3152// if (encoding_type != NULL) 3153// { 3154// if (encoding_type != DIE_IS_BEING_PARSED) 3155// type_sp->SetEncodingType(encoding_type); 3156// else 3157// m_indirect_fixups.push_back(type_sp.get()); 3158// } 3159 } 3160 break; 3161 3162 case DW_TAG_structure_type: 3163 case DW_TAG_union_type: 3164 case DW_TAG_class_type: 3165 { 3166 // Set a bit that lets us know that we are currently parsing this 3167 m_die_to_type[die] = DIE_IS_BEING_PARSED; 3168 3169 LanguageType class_language = eLanguageTypeUnknown; 3170 //bool struct_is_class = false; 3171 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3172 if (num_attributes > 0) 3173 { 3174 uint32_t i; 3175 for (i=0; i<num_attributes; ++i) 3176 { 3177 attr = attributes.AttributeAtIndex(i); 3178 DWARFFormValue form_value; 3179 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3180 { 3181 switch (attr) 3182 { 3183 case DW_AT_decl_file: 3184 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); 3185 break; 3186 3187 case DW_AT_decl_line: 3188 decl.SetLine(form_value.Unsigned()); 3189 break; 3190 3191 case DW_AT_decl_column: 3192 decl.SetColumn(form_value.Unsigned()); 3193 break; 3194 3195 case DW_AT_name: 3196 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3197 type_name_const_str.SetCString(type_name_cstr); 3198 break; 3199 3200 case DW_AT_byte_size: 3201 byte_size = form_value.Unsigned(); 3202 byte_size_valid = true; 3203 break; 3204 3205 case DW_AT_accessibility: 3206 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); 3207 break; 3208 3209 case DW_AT_declaration: 3210 is_forward_declaration = form_value.Unsigned() != 0; 3211 break; 3212 3213 case DW_AT_APPLE_runtime_class: 3214 class_language = (LanguageType)form_value.Signed(); 3215 break; 3216 3217 case DW_AT_allocated: 3218 case DW_AT_associated: 3219 case DW_AT_data_location: 3220 case DW_AT_description: 3221 case DW_AT_start_scope: 3222 case DW_AT_visibility: 3223 default: 3224 case DW_AT_sibling: 3225 break; 3226 } 3227 } 3228 } 3229 } 3230 3231 UniqueDWARFASTType unique_ast_entry; 3232 if (decl.IsValid()) 3233 { 3234 if (GetUniqueDWARFASTTypeMap().Find (type_name_const_str, 3235 this, 3236 dwarf_cu, 3237 die, 3238 decl, 3239 byte_size_valid ? byte_size : -1, 3240 unique_ast_entry)) 3241 { 3242 // We have already parsed this type or from another 3243 // compile unit. GCC loves to use the "one definition 3244 // rule" which can result in multiple definitions 3245 // of the same class over and over in each compile 3246 // unit. 3247 type_sp = unique_ast_entry.m_type_sp; 3248 if (type_sp) 3249 { 3250 m_die_to_type[die] = type_sp.get(); 3251 return type_sp; 3252 } 3253 } 3254 } 3255 3256 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr); 3257 3258 int tag_decl_kind = -1; 3259 AccessType default_accessibility = eAccessNone; 3260 if (tag == DW_TAG_structure_type) 3261 { 3262 tag_decl_kind = clang::TTK_Struct; 3263 default_accessibility = eAccessPublic; 3264 } 3265 else if (tag == DW_TAG_union_type) 3266 { 3267 tag_decl_kind = clang::TTK_Union; 3268 default_accessibility = eAccessPublic; 3269 } 3270 else if (tag == DW_TAG_class_type) 3271 { 3272 tag_decl_kind = clang::TTK_Class; 3273 default_accessibility = eAccessPrivate; 3274 } 3275 3276 3277 if (is_forward_declaration) 3278 { 3279 // We have a forward declaration to a type and we need 3280 // to try and find a full declaration. We look in the 3281 // current type index just in case we have a forward 3282 // declaration followed by an actual declarations in the 3283 // DWARF. If this fails, we need to look elsewhere... 3284 3285 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); 3286 3287 if (!type_sp && m_debug_map_symfile) 3288 { 3289 // We weren't able to find a full declaration in 3290 // this DWARF, see if we have a declaration anywhere 3291 // else... 3292 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str); 3293 } 3294 3295 if (type_sp) 3296 { 3297 // We found a real definition for this type elsewhere 3298 // so lets use it and cache the fact that we found 3299 // a complete type for this die 3300 m_die_to_type[die] = type_sp.get(); 3301 return type_sp; 3302 } 3303 } 3304 assert (tag_decl_kind != -1); 3305 bool clang_type_was_created = false; 3306 clang_type = m_forward_decl_die_to_clang_type.lookup (die); 3307 if (clang_type == NULL) 3308 { 3309 clang_type_was_created = true; 3310 clang_type = ast.CreateRecordType (type_name_cstr, 3311 tag_decl_kind, 3312 GetClangDeclContextForDIE (dwarf_cu, die), 3313 class_language); 3314 } 3315 3316 // Store a forward declaration to this class type in case any 3317 // parameters in any class methods need it for the clang 3318 // types for function prototypes. 3319 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); 3320 type_sp.reset (new Type (die->GetOffset(), 3321 this, 3322 type_name_const_str, 3323 byte_size, 3324 NULL, 3325 LLDB_INVALID_UID, 3326 Type::eEncodingIsUID, 3327 &decl, 3328 clang_type, 3329 Type::eResolveStateForward)); 3330 3331 3332 // Add our type to the unique type map so we don't 3333 // end up creating many copies of the same type over 3334 // and over in the ASTContext for our module 3335 unique_ast_entry.m_type_sp = type_sp; 3336 unique_ast_entry.m_symfile = this; 3337 unique_ast_entry.m_cu = dwarf_cu; 3338 unique_ast_entry.m_die = die; 3339 unique_ast_entry.m_declaration = decl; 3340 GetUniqueDWARFASTTypeMap().Insert (type_name_const_str, 3341 unique_ast_entry); 3342 3343 if (die->HasChildren() == false && is_forward_declaration == false) 3344 { 3345 // No children for this struct/union/class, lets finish it 3346 ast.StartTagDeclarationDefinition (clang_type); 3347 ast.CompleteTagDeclarationDefinition (clang_type); 3348 } 3349 else if (clang_type_was_created) 3350 { 3351 // Leave this as a forward declaration until we need 3352 // to know the details of the type. lldb_private::Type 3353 // will automatically call the SymbolFile virtual function 3354 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)" 3355 // When the definition needs to be defined. 3356 m_forward_decl_die_to_clang_type[die] = clang_type; 3357 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die; 3358 ClangASTContext::SetHasExternalStorage (clang_type, true); 3359 } 3360 } 3361 break; 3362 3363 case DW_TAG_enumeration_type: 3364 { 3365 // Set a bit that lets us know that we are currently parsing this 3366 m_die_to_type[die] = DIE_IS_BEING_PARSED; 3367 3368 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET; 3369 3370 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3371 if (num_attributes > 0) 3372 { 3373 uint32_t i; 3374 3375 for (i=0; i<num_attributes; ++i) 3376 { 3377 attr = attributes.AttributeAtIndex(i); 3378 DWARFFormValue form_value; 3379 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3380 { 3381 switch (attr) 3382 { 3383 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3384 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3385 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3386 case DW_AT_name: 3387 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3388 type_name_const_str.SetCString(type_name_cstr); 3389 break; 3390 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break; 3391 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break; 3392 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 3393 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 3394 case DW_AT_allocated: 3395 case DW_AT_associated: 3396 case DW_AT_bit_stride: 3397 case DW_AT_byte_stride: 3398 case DW_AT_data_location: 3399 case DW_AT_description: 3400 case DW_AT_start_scope: 3401 case DW_AT_visibility: 3402 case DW_AT_specification: 3403 case DW_AT_abstract_origin: 3404 case DW_AT_sibling: 3405 break; 3406 } 3407 } 3408 } 3409 3410 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr); 3411 3412 clang_type_t enumerator_clang_type = NULL; 3413 clang_type = m_forward_decl_die_to_clang_type.lookup (die); 3414 if (clang_type == NULL) 3415 { 3416 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, 3417 DW_ATE_signed, 3418 byte_size * 8); 3419 clang_type = ast.CreateEnumerationType (type_name_cstr, 3420 GetClangDeclContextForDIE (dwarf_cu, die), 3421 decl, 3422 enumerator_clang_type); 3423 } 3424 else 3425 { 3426 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type); 3427 assert (enumerator_clang_type != NULL); 3428 } 3429 3430 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); 3431 3432 type_sp.reset( new Type (die->GetOffset(), 3433 this, 3434 type_name_const_str, 3435 byte_size, 3436 NULL, 3437 encoding_uid, 3438 Type::eEncodingIsUID, 3439 &decl, 3440 clang_type, 3441 Type::eResolveStateForward)); 3442 3443#if LEAVE_ENUMS_FORWARD_DECLARED 3444 // Leave this as a forward declaration until we need 3445 // to know the details of the type. lldb_private::Type 3446 // will automatically call the SymbolFile virtual function 3447 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)" 3448 // When the definition needs to be defined. 3449 m_forward_decl_die_to_clang_type[die] = clang_type; 3450 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die; 3451 ClangASTContext::SetHasExternalStorage (clang_type, true); 3452#else 3453 ast.StartTagDeclarationDefinition (clang_type); 3454 if (die->HasChildren()) 3455 { 3456 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu)); 3457 ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die); 3458 } 3459 ast.CompleteTagDeclarationDefinition (clang_type); 3460#endif 3461 } 3462 } 3463 break; 3464 3465 case DW_TAG_inlined_subroutine: 3466 case DW_TAG_subprogram: 3467 case DW_TAG_subroutine_type: 3468 { 3469 // Set a bit that lets us know that we are currently parsing this 3470 m_die_to_type[die] = DIE_IS_BEING_PARSED; 3471 3472 const char *mangled = NULL; 3473 dw_offset_t type_die_offset = DW_INVALID_OFFSET; 3474 bool is_variadic = false; 3475 bool is_inline = false; 3476 bool is_static = false; 3477 bool is_virtual = false; 3478 bool is_explicit = false; 3479 3480 unsigned type_quals = 0; 3481 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern 3482 3483 3484 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3485 if (num_attributes > 0) 3486 { 3487 uint32_t i; 3488 for (i=0; i<num_attributes; ++i) 3489 { 3490 attr = attributes.AttributeAtIndex(i); 3491 DWARFFormValue form_value; 3492 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3493 { 3494 switch (attr) 3495 { 3496 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3497 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3498 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3499 case DW_AT_name: 3500 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3501 type_name_const_str.SetCString(type_name_cstr); 3502 break; 3503 3504 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break; 3505 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; 3506 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 3507 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 3508 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break; 3509 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break; 3510 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break; 3511 3512 case DW_AT_external: 3513 if (form_value.Unsigned()) 3514 { 3515 if (storage == clang::SC_None) 3516 storage = clang::SC_Extern; 3517 else 3518 storage = clang::SC_PrivateExtern; 3519 } 3520 break; 3521 3522 case DW_AT_allocated: 3523 case DW_AT_associated: 3524 case DW_AT_address_class: 3525 case DW_AT_artificial: 3526 case DW_AT_calling_convention: 3527 case DW_AT_data_location: 3528 case DW_AT_elemental: 3529 case DW_AT_entry_pc: 3530 case DW_AT_frame_base: 3531 case DW_AT_high_pc: 3532 case DW_AT_low_pc: 3533 case DW_AT_object_pointer: 3534 case DW_AT_prototyped: 3535 case DW_AT_pure: 3536 case DW_AT_ranges: 3537 case DW_AT_recursive: 3538 case DW_AT_return_addr: 3539 case DW_AT_segment: 3540 case DW_AT_specification: 3541 case DW_AT_start_scope: 3542 case DW_AT_static_link: 3543 case DW_AT_trampoline: 3544 case DW_AT_visibility: 3545 case DW_AT_vtable_elem_location: 3546 case DW_AT_abstract_origin: 3547 case DW_AT_description: 3548 case DW_AT_sibling: 3549 break; 3550 } 3551 } 3552 } 3553 } 3554 3555 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr); 3556 3557 clang_type_t return_clang_type = NULL; 3558 Type *func_type = NULL; 3559 3560 if (type_die_offset != DW_INVALID_OFFSET) 3561 func_type = ResolveTypeUID(type_die_offset); 3562 3563 if (func_type) 3564 return_clang_type = func_type->GetClangLayoutType(); 3565 else 3566 return_clang_type = ast.GetBuiltInType_void(); 3567 3568 3569 std::vector<clang_type_t> function_param_types; 3570 std::vector<clang::ParmVarDecl*> function_param_decls; 3571 3572 // Parse the function children for the parameters 3573 3574 const DWARFDebugInfoEntry *class_die = die->GetParent(); 3575 if (class_die && (class_die->Tag() == DW_TAG_structure_type || 3576 class_die->Tag() == DW_TAG_class_type)) 3577 is_static = true; 3578 3579 if (die->HasChildren()) 3580 { 3581 bool skip_artificial = true; 3582 ParseChildParameters (sc, 3583 type_sp, 3584 dwarf_cu, 3585 die, 3586 skip_artificial, 3587 is_static, 3588 type_list, 3589 function_param_types, 3590 function_param_decls, 3591 type_quals); 3592 } 3593 3594 // clang_type will get the function prototype clang type after this call 3595 clang_type = ast.CreateFunctionType (return_clang_type, 3596 &function_param_types[0], 3597 function_param_types.size(), 3598 is_variadic, 3599 type_quals); 3600 3601 if (type_name_cstr) 3602 { 3603 bool type_handled = false; 3604 const DWARFDebugInfoEntry *parent_die = die->GetParent(); 3605 if (tag == DW_TAG_subprogram) 3606 { 3607 if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+')) 3608 { 3609 // We need to find the DW_TAG_class_type or 3610 // DW_TAG_struct_type by name so we can add this 3611 // as a member function of the class. 3612 const char *class_name_start = type_name_cstr + 2; 3613 const char *class_name_end = ::strchr (class_name_start, ' '); 3614 SymbolContext empty_sc; 3615 clang_type_t class_opaque_type = NULL; 3616 if (class_name_start < class_name_end) 3617 { 3618 ConstString class_name (class_name_start, class_name_end - class_name_start); 3619 TypeList types; 3620 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types); 3621 if (match_count > 0) 3622 { 3623 for (uint32_t i=0; i<match_count; ++i) 3624 { 3625 Type *type = types.GetTypeAtIndex (i).get(); 3626 clang_type_t type_clang_forward_type = type->GetClangForwardType(); 3627 if (ClangASTContext::IsObjCClassType (type_clang_forward_type)) 3628 { 3629 class_opaque_type = type_clang_forward_type; 3630 break; 3631 } 3632 } 3633 } 3634 } 3635 3636 if (class_opaque_type) 3637 { 3638 // If accessibility isn't set to anything valid, assume public for 3639 // now... 3640 if (accessibility == eAccessNone) 3641 accessibility = eAccessPublic; 3642 3643 clang::ObjCMethodDecl *objc_method_decl; 3644 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type, 3645 type_name_cstr, 3646 clang_type, 3647 accessibility); 3648 type_handled = objc_method_decl != NULL; 3649 } 3650 } 3651 else if (parent_die->Tag() == DW_TAG_class_type || 3652 parent_die->Tag() == DW_TAG_structure_type) 3653 { 3654 // Look at the parent of this DIE and see if is is 3655 // a class or struct and see if this is actually a 3656 // C++ method 3657 Type *class_type = ResolveType (dwarf_cu, parent_die); 3658 if (class_type) 3659 { 3660 clang_type_t class_opaque_type = class_type->GetClangForwardType(); 3661 if (ClangASTContext::IsCXXClassType (class_opaque_type)) 3662 { 3663 // Neither GCC 4.2 nor clang++ currently set a valid accessibility 3664 // in the DWARF for C++ methods... Default to public for now... 3665 if (accessibility == eAccessNone) 3666 accessibility = eAccessPublic; 3667 3668 if (!is_static && !die->HasChildren()) 3669 { 3670 // We have a C++ member function with no children (this pointer!) 3671 // and clang will get mad if we try and make a function that isn't 3672 // well formed in the DWARF, so we will just skip it... 3673 type_handled = true; 3674 } 3675 else 3676 { 3677 clang::CXXMethodDecl *cxx_method_decl; 3678 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type, 3679 type_name_cstr, 3680 clang_type, 3681 accessibility, 3682 is_virtual, 3683 is_static, 3684 is_inline, 3685 is_explicit); 3686 type_handled = cxx_method_decl != NULL; 3687 } 3688 } 3689 } 3690 } 3691 } 3692 3693 if (!type_handled) 3694 { 3695 // We just have a function that isn't part of a class 3696 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr, 3697 clang_type, 3698 storage, 3699 is_inline); 3700 3701 // Add the decl to our DIE to decl context map 3702 assert (function_decl); 3703 LinkDeclContextToDIE(function_decl, die); 3704 if (!function_param_decls.empty()) 3705 ast.SetFunctionParameters (function_decl, 3706 &function_param_decls.front(), 3707 function_param_decls.size()); 3708 } 3709 } 3710 type_sp.reset( new Type (die->GetOffset(), 3711 this, 3712 type_name_const_str, 3713 0, 3714 NULL, 3715 LLDB_INVALID_UID, 3716 Type::eEncodingIsUID, 3717 &decl, 3718 clang_type, 3719 Type::eResolveStateFull)); 3720 assert(type_sp.get()); 3721 } 3722 break; 3723 3724 case DW_TAG_array_type: 3725 { 3726 // Set a bit that lets us know that we are currently parsing this 3727 m_die_to_type[die] = DIE_IS_BEING_PARSED; 3728 3729 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET; 3730 int64_t first_index = 0; 3731 uint32_t byte_stride = 0; 3732 uint32_t bit_stride = 0; 3733 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3734 3735 if (num_attributes > 0) 3736 { 3737 uint32_t i; 3738 for (i=0; i<num_attributes; ++i) 3739 { 3740 attr = attributes.AttributeAtIndex(i); 3741 DWARFFormValue form_value; 3742 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3743 { 3744 switch (attr) 3745 { 3746 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 3747 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 3748 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 3749 case DW_AT_name: 3750 type_name_cstr = form_value.AsCString(&get_debug_str_data()); 3751 type_name_const_str.SetCString(type_name_cstr); 3752 break; 3753 3754 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break; 3755 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break; 3756 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break; 3757 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break; 3758 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 3759 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break; 3760 case DW_AT_allocated: 3761 case DW_AT_associated: 3762 case DW_AT_data_location: 3763 case DW_AT_description: 3764 case DW_AT_ordering: 3765 case DW_AT_start_scope: 3766 case DW_AT_visibility: 3767 case DW_AT_specification: 3768 case DW_AT_abstract_origin: 3769 case DW_AT_sibling: 3770 break; 3771 } 3772 } 3773 } 3774 3775 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr); 3776 3777 Type *element_type = ResolveTypeUID(type_die_offset); 3778 3779 if (element_type) 3780 { 3781 std::vector<uint64_t> element_orders; 3782 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride); 3783 // We have an array that claims to have no members, lets give it at least one member... 3784 if (element_orders.empty()) 3785 element_orders.push_back (1); 3786 if (byte_stride == 0 && bit_stride == 0) 3787 byte_stride = element_type->GetByteSize(); 3788 clang_type_t array_element_type = element_type->GetClangFullType(); 3789 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; 3790 uint64_t num_elements = 0; 3791 std::vector<uint64_t>::const_reverse_iterator pos; 3792 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend(); 3793 for (pos = element_orders.rbegin(); pos != end; ++pos) 3794 { 3795 num_elements = *pos; 3796 clang_type = ast.CreateArrayType (array_element_type, 3797 num_elements, 3798 num_elements * array_element_bit_stride); 3799 array_element_type = clang_type; 3800 array_element_bit_stride = array_element_bit_stride * num_elements; 3801 } 3802 ConstString empty_name; 3803 type_sp.reset( new Type (die->GetOffset(), 3804 this, 3805 empty_name, 3806 array_element_bit_stride / 8, 3807 NULL, 3808 type_die_offset, 3809 Type::eEncodingIsUID, 3810 &decl, 3811 clang_type, 3812 Type::eResolveStateFull)); 3813 type_sp->SetEncodingType (element_type); 3814 } 3815 } 3816 } 3817 break; 3818 3819 case DW_TAG_ptr_to_member_type: 3820 { 3821 dw_offset_t type_die_offset = DW_INVALID_OFFSET; 3822 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET; 3823 3824 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 3825 3826 if (num_attributes > 0) { 3827 uint32_t i; 3828 for (i=0; i<num_attributes; ++i) 3829 { 3830 attr = attributes.AttributeAtIndex(i); 3831 DWARFFormValue form_value; 3832 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 3833 { 3834 switch (attr) 3835 { 3836 case DW_AT_type: 3837 type_die_offset = form_value.Reference(dwarf_cu); break; 3838 case DW_AT_containing_type: 3839 containing_type_die_offset = form_value.Reference(dwarf_cu); break; 3840 } 3841 } 3842 } 3843 3844 Type *pointee_type = ResolveTypeUID(type_die_offset); 3845 Type *class_type = ResolveTypeUID(containing_type_die_offset); 3846 3847 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType(); 3848 clang_type_t class_clang_type = class_type->GetClangLayoutType(); 3849 3850 clang_type = ast.CreateMemberPointerType(pointee_clang_type, 3851 class_clang_type); 3852 3853 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(), 3854 clang_type) / 8; 3855 3856 type_sp.reset( new Type (die->GetOffset(), 3857 this, 3858 type_name_const_str, 3859 byte_size, 3860 NULL, 3861 LLDB_INVALID_UID, 3862 Type::eEncodingIsUID, 3863 NULL, 3864 clang_type, 3865 Type::eResolveStateForward)); 3866 } 3867 3868 break; 3869 } 3870 default: 3871 assert(false && "Unhandled type tag!"); 3872 break; 3873 } 3874 3875 if (type_sp.get()) 3876 { 3877 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die); 3878 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 3879 3880 SymbolContextScope * symbol_context_scope = NULL; 3881 if (sc_parent_tag == DW_TAG_compile_unit) 3882 { 3883 symbol_context_scope = sc.comp_unit; 3884 } 3885 else if (sc.function != NULL) 3886 { 3887 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset()); 3888 if (symbol_context_scope == NULL) 3889 symbol_context_scope = sc.function; 3890 } 3891 3892 if (symbol_context_scope != NULL) 3893 { 3894 type_sp->SetSymbolContextScope(symbol_context_scope); 3895 } 3896 3897 // We are ready to put this type into the uniqued list up at the module level 3898 type_list->Insert (type_sp); 3899 3900 m_die_to_type[die] = type_sp.get(); 3901 } 3902 } 3903 else if (type_ptr != DIE_IS_BEING_PARSED) 3904 { 3905 type_sp = type_list->FindType(type_ptr->GetID()); 3906 } 3907 } 3908 return type_sp; 3909} 3910 3911size_t 3912SymbolFileDWARF::ParseTypes 3913( 3914 const SymbolContext& sc, 3915 DWARFCompileUnit* dwarf_cu, 3916 const DWARFDebugInfoEntry *die, 3917 bool parse_siblings, 3918 bool parse_children 3919) 3920{ 3921 size_t types_added = 0; 3922 while (die != NULL) 3923 { 3924 bool type_is_new = false; 3925 if (ParseType(sc, dwarf_cu, die, &type_is_new).get()) 3926 { 3927 if (type_is_new) 3928 ++types_added; 3929 } 3930 3931 if (parse_children && die->HasChildren()) 3932 { 3933 if (die->Tag() == DW_TAG_subprogram) 3934 { 3935 SymbolContext child_sc(sc); 3936 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get(); 3937 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true); 3938 } 3939 else 3940 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true); 3941 } 3942 3943 if (parse_siblings) 3944 die = die->GetSibling(); 3945 else 3946 die = NULL; 3947 } 3948 return types_added; 3949} 3950 3951 3952size_t 3953SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc) 3954{ 3955 assert(sc.comp_unit && sc.function); 3956 size_t functions_added = 0; 3957 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 3958 if (dwarf_cu) 3959 { 3960 dw_offset_t function_die_offset = sc.function->GetID(); 3961 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset); 3962 if (function_die) 3963 { 3964 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true); 3965 } 3966 } 3967 3968 return functions_added; 3969} 3970 3971 3972size_t 3973SymbolFileDWARF::ParseTypes (const SymbolContext &sc) 3974{ 3975 // At least a compile unit must be valid 3976 assert(sc.comp_unit); 3977 size_t types_added = 0; 3978 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID()); 3979 if (dwarf_cu) 3980 { 3981 if (sc.function) 3982 { 3983 dw_offset_t function_die_offset = sc.function->GetID(); 3984 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset); 3985 if (func_die && func_die->HasChildren()) 3986 { 3987 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true); 3988 } 3989 } 3990 else 3991 { 3992 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE(); 3993 if (dwarf_cu_die && dwarf_cu_die->HasChildren()) 3994 { 3995 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true); 3996 } 3997 } 3998 } 3999 4000 return types_added; 4001} 4002 4003size_t 4004SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc) 4005{ 4006 if (sc.comp_unit != NULL) 4007 { 4008 DWARFDebugInfo* info = DebugInfo(); 4009 if (info == NULL) 4010 return 0; 4011 4012 uint32_t cu_idx = UINT32_MAX; 4013 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get(); 4014 4015 if (dwarf_cu == NULL) 4016 return 0; 4017 4018 if (sc.function) 4019 { 4020 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID()); 4021 4022 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS); 4023 assert (func_lo_pc != DW_INVALID_ADDRESS); 4024 4025 const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true); 4026 4027 // Let all blocks know they have parse all their variables 4028 sc.function->GetBlock (false).SetDidParseVariables (true, true); 4029 4030 return num_variables; 4031 } 4032 else if (sc.comp_unit) 4033 { 4034 uint32_t vars_added = 0; 4035 VariableListSP variables (sc.comp_unit->GetVariableList(false)); 4036 4037 if (variables.get() == NULL) 4038 { 4039 variables.reset(new VariableList()); 4040 sc.comp_unit->SetVariableList(variables); 4041 4042 // Index if we already haven't to make sure the compile units 4043 // get indexed and make their global DIE index list 4044 if (!m_indexed) 4045 Index (); 4046 4047 std::vector<NameToDIE::Info> global_die_info_array; 4048 const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (cu_idx, global_die_info_array); 4049 for (size_t idx=0; idx<num_globals; ++idx) 4050 { 4051 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetDIEAtIndexUnchecked(global_die_info_array[idx].die_idx), LLDB_INVALID_ADDRESS)); 4052 if (var_sp) 4053 { 4054 variables->AddVariableIfUnique (var_sp); 4055 ++vars_added; 4056 } 4057 } 4058 } 4059 return vars_added; 4060 } 4061 } 4062 return 0; 4063} 4064 4065 4066VariableSP 4067SymbolFileDWARF::ParseVariableDIE 4068( 4069 const SymbolContext& sc, 4070 DWARFCompileUnit* dwarf_cu, 4071 const DWARFDebugInfoEntry *die, 4072 const lldb::addr_t func_low_pc 4073) 4074{ 4075 4076 VariableSP var_sp (m_die_to_variable_sp[die]); 4077 if (var_sp) 4078 return var_sp; // Already been parsed! 4079 4080 const dw_tag_t tag = die->Tag(); 4081 DWARFDebugInfoEntry::Attributes attributes; 4082 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes); 4083 if (num_attributes > 0) 4084 { 4085 const char *name = NULL; 4086 const char *mangled = NULL; 4087 Declaration decl; 4088 uint32_t i; 4089 Type *var_type = NULL; 4090 DWARFExpression location; 4091 bool is_external = false; 4092 bool is_artificial = false; 4093 bool location_is_const_value_data = false; 4094 AccessType accessibility = eAccessNone; 4095 4096 for (i=0; i<num_attributes; ++i) 4097 { 4098 dw_attr_t attr = attributes.AttributeAtIndex(i); 4099 DWARFFormValue form_value; 4100 if (attributes.ExtractFormValueAtIndex(this, i, form_value)) 4101 { 4102 switch (attr) 4103 { 4104 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break; 4105 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break; 4106 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break; 4107 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break; 4108 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break; 4109 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break; 4110 case DW_AT_external: is_external = form_value.Unsigned() != 0; break; 4111 case DW_AT_const_value: 4112 location_is_const_value_data = true; 4113 // Fall through... 4114 case DW_AT_location: 4115 { 4116 if (form_value.BlockData()) 4117 { 4118 const DataExtractor& debug_info_data = get_debug_info_data(); 4119 4120 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart(); 4121 uint32_t block_length = form_value.Unsigned(); 4122 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length); 4123 } 4124 else 4125 { 4126 const DataExtractor& debug_loc_data = get_debug_loc_data(); 4127 const dw_offset_t debug_loc_offset = form_value.Unsigned(); 4128 4129 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset); 4130 if (loc_list_length > 0) 4131 { 4132 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length); 4133 assert (func_low_pc != LLDB_INVALID_ADDRESS); 4134 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress()); 4135 } 4136 } 4137 } 4138 break; 4139 4140 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break; 4141 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; 4142 case DW_AT_declaration: 4143 case DW_AT_description: 4144 case DW_AT_endianity: 4145 case DW_AT_segment: 4146 case DW_AT_start_scope: 4147 case DW_AT_visibility: 4148 default: 4149 case DW_AT_abstract_origin: 4150 case DW_AT_sibling: 4151 case DW_AT_specification: 4152 break; 4153 } 4154 } 4155 } 4156 4157 if (location.IsValid()) 4158 { 4159 assert(var_type != DIE_IS_BEING_PARSED); 4160 4161 ValueType scope = eValueTypeInvalid; 4162 4163 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die); 4164 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 4165 4166 if (tag == DW_TAG_formal_parameter) 4167 scope = eValueTypeVariableArgument; 4168 else if (is_external || parent_tag == DW_TAG_compile_unit) 4169 scope = eValueTypeVariableGlobal; 4170 else 4171 scope = eValueTypeVariableLocal; 4172 4173 SymbolContextScope * symbol_context_scope = NULL; 4174 if (parent_tag == DW_TAG_compile_unit) 4175 { 4176 symbol_context_scope = sc.comp_unit; 4177 } 4178 else if (sc.function != NULL) 4179 { 4180 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset()); 4181 if (symbol_context_scope == NULL) 4182 symbol_context_scope = sc.function; 4183 } 4184 4185 assert(symbol_context_scope != NULL); 4186 var_sp.reset (new Variable(die->GetOffset(), 4187 name, 4188 mangled, 4189 var_type, 4190 scope, 4191 symbol_context_scope, 4192 &decl, 4193 location, 4194 is_external, 4195 is_artificial)); 4196 4197 var_sp->SetLocationIsConstantValueData (location_is_const_value_data); 4198 } 4199 } 4200 // Cache var_sp even if NULL (the variable was just a specification or 4201 // was missing vital information to be able to be displayed in the debugger 4202 // (missing location due to optimization, etc)) so we don't re-parse 4203 // this DIE over and over later... 4204 m_die_to_variable_sp[die] = var_sp; 4205 return var_sp; 4206} 4207 4208 4209const DWARFDebugInfoEntry * 4210SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset, 4211 dw_offset_t spec_block_die_offset, 4212 DWARFCompileUnit **result_die_cu_handle) 4213{ 4214 // Give the concrete function die specified by "func_die_offset", find the 4215 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points 4216 // to "spec_block_die_offset" 4217 DWARFDebugInfo* info = DebugInfo(); 4218 4219 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle); 4220 if (die) 4221 { 4222 assert (*result_die_cu_handle); 4223 return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle); 4224 } 4225 return NULL; 4226} 4227 4228 4229const DWARFDebugInfoEntry * 4230SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu, 4231 const DWARFDebugInfoEntry *die, 4232 dw_offset_t spec_block_die_offset, 4233 DWARFCompileUnit **result_die_cu_handle) 4234{ 4235 if (die) 4236 { 4237 switch (die->Tag()) 4238 { 4239 case DW_TAG_subprogram: 4240 case DW_TAG_inlined_subroutine: 4241 case DW_TAG_lexical_block: 4242 { 4243 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset) 4244 { 4245 *result_die_cu_handle = dwarf_cu; 4246 return die; 4247 } 4248 4249 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset) 4250 { 4251 *result_die_cu_handle = dwarf_cu; 4252 return die; 4253 } 4254 } 4255 break; 4256 } 4257 4258 // Give the concrete function die specified by "func_die_offset", find the 4259 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points 4260 // to "spec_block_die_offset" 4261 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling()) 4262 { 4263 const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu, 4264 child_die, 4265 spec_block_die_offset, 4266 result_die_cu_handle); 4267 if (result_die) 4268 return result_die; 4269 } 4270 } 4271 4272 *result_die_cu_handle = NULL; 4273 return NULL; 4274} 4275 4276size_t 4277SymbolFileDWARF::ParseVariables 4278( 4279 const SymbolContext& sc, 4280 DWARFCompileUnit* dwarf_cu, 4281 const lldb::addr_t func_low_pc, 4282 const DWARFDebugInfoEntry *orig_die, 4283 bool parse_siblings, 4284 bool parse_children, 4285 VariableList* cc_variable_list 4286) 4287{ 4288 if (orig_die == NULL) 4289 return 0; 4290 4291 VariableListSP variable_list_sp; 4292 4293 size_t vars_added = 0; 4294 const DWARFDebugInfoEntry *die = orig_die; 4295 while (die != NULL) 4296 { 4297 dw_tag_t tag = die->Tag(); 4298 4299 // Check to see if we have already parsed this variable or constant? 4300 if (m_die_to_variable_sp[die]) 4301 { 4302 if (cc_variable_list) 4303 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]); 4304 } 4305 else 4306 { 4307 // We haven't already parsed it, lets do that now. 4308 if ((tag == DW_TAG_variable) || 4309 (tag == DW_TAG_constant) || 4310 (tag == DW_TAG_formal_parameter && sc.function)) 4311 { 4312 if (variable_list_sp.get() == NULL) 4313 { 4314 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die); 4315 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; 4316 switch (parent_tag) 4317 { 4318 case DW_TAG_compile_unit: 4319 if (sc.comp_unit != NULL) 4320 { 4321 variable_list_sp = sc.comp_unit->GetVariableList(false); 4322 if (variable_list_sp.get() == NULL) 4323 { 4324 variable_list_sp.reset(new VariableList()); 4325 sc.comp_unit->SetVariableList(variable_list_sp); 4326 } 4327 } 4328 else 4329 { 4330 fprintf (stderr, 4331 "error: parent 0x%8.8x %s with no valid compile unit in symbol context for 0x%8.8x %s.\n", 4332 sc_parent_die->GetOffset(), 4333 DW_TAG_value_to_name (parent_tag), 4334 orig_die->GetOffset(), 4335 DW_TAG_value_to_name (orig_die->Tag())); 4336 } 4337 break; 4338 4339 case DW_TAG_subprogram: 4340 case DW_TAG_inlined_subroutine: 4341 case DW_TAG_lexical_block: 4342 if (sc.function != NULL) 4343 { 4344 // Check to see if we already have parsed the variables for the given scope 4345 4346 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset()); 4347 if (block == NULL) 4348 { 4349 // This must be a specification or abstract origin with 4350 // a concrete block couterpart in the current function. We need 4351 // to find the concrete block so we can correctly add the 4352 // variable to it 4353 DWARFCompileUnit *concrete_block_die_cu = dwarf_cu; 4354 const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(), 4355 sc_parent_die->GetOffset(), 4356 &concrete_block_die_cu); 4357 if (concrete_block_die) 4358 block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die->GetOffset()); 4359 } 4360 4361 if (block != NULL) 4362 { 4363 const bool can_create = false; 4364 variable_list_sp = block->GetBlockVariableList (can_create); 4365 if (variable_list_sp.get() == NULL) 4366 { 4367 variable_list_sp.reset(new VariableList()); 4368 block->SetVariableList(variable_list_sp); 4369 } 4370 } 4371 } 4372 break; 4373 4374 default: 4375 fprintf (stderr, 4376 "error: didn't find appropriate parent DIE for variable list for 0x%8.8x %s.\n", 4377 orig_die->GetOffset(), 4378 DW_TAG_value_to_name (orig_die->Tag())); 4379 break; 4380 } 4381 } 4382 4383 if (variable_list_sp) 4384 { 4385 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc)); 4386 if (var_sp) 4387 { 4388 variable_list_sp->AddVariableIfUnique (var_sp); 4389 if (cc_variable_list) 4390 cc_variable_list->AddVariableIfUnique (var_sp); 4391 ++vars_added; 4392 } 4393 } 4394 } 4395 } 4396 4397 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram); 4398 4399 if (!skip_children && parse_children && die->HasChildren()) 4400 { 4401 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list); 4402 } 4403 4404 if (parse_siblings) 4405 die = die->GetSibling(); 4406 else 4407 die = NULL; 4408 } 4409 return vars_added; 4410} 4411 4412//------------------------------------------------------------------ 4413// PluginInterface protocol 4414//------------------------------------------------------------------ 4415const char * 4416SymbolFileDWARF::GetPluginName() 4417{ 4418 return "SymbolFileDWARF"; 4419} 4420 4421const char * 4422SymbolFileDWARF::GetShortPluginName() 4423{ 4424 return GetPluginNameStatic(); 4425} 4426 4427uint32_t 4428SymbolFileDWARF::GetPluginVersion() 4429{ 4430 return 1; 4431} 4432 4433void 4434SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl) 4435{ 4436 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; 4437 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); 4438 if (clang_type) 4439 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); 4440} 4441 4442void 4443SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl) 4444{ 4445 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; 4446 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); 4447 if (clang_type) 4448 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); 4449} 4450 4451void 4452SymbolFileDWARF::DumpIndexes () 4453{ 4454 StreamFile s(stdout, false); 4455 4456 s.Printf ("DWARF index for (%s) '%s/%s':", 4457 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(), 4458 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(), 4459 GetObjectFile()->GetFileSpec().GetFilename().AsCString()); 4460 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s); 4461 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s); 4462 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s); 4463 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s); 4464 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s); 4465 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s); 4466 s.Printf("\nTypes:\n"); m_type_index.Dump (&s); 4467 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s); 4468} 4469 4470void 4471SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context, 4472 const char *name, 4473 llvm::SmallVectorImpl <clang::NamedDecl *> *results) 4474{ 4475 DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context); 4476 4477 if (iter == m_decl_ctx_to_die.end()) 4478 return; 4479 4480 const DWARFDebugInfoEntry *context_die = iter->second; 4481 4482 if (!results) 4483 return; 4484 4485 DWARFDebugInfo* info = DebugInfo(); 4486 4487 std::vector<NameToDIE::Info> die_info_array; 4488 4489 size_t num_matches = m_type_index.Find (ConstString(name), die_info_array); 4490 4491 if (num_matches) 4492 { 4493 for (int i = 0; 4494 i < num_matches; 4495 ++i) 4496 { 4497 DWARFCompileUnit* compile_unit = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); 4498 compile_unit->ExtractDIEsIfNeeded (false); 4499 const DWARFDebugInfoEntry *die = compile_unit->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); 4500 4501 if (die->GetParent() != context_die) 4502 continue; 4503 4504 Type *matching_type = ResolveType (compile_unit, die); 4505 4506 lldb::clang_type_t type = matching_type->GetClangFullType(); 4507 clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type); 4508 4509 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr())) 4510 { 4511 clang::TagDecl *tag_decl = tag_type->getDecl(); 4512 results->push_back(tag_decl); 4513 } 4514 else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr())) 4515 { 4516 clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); 4517 results->push_back(typedef_decl); 4518 } 4519 } 4520 } 4521} 4522 4523void 4524SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton, 4525 const clang::DeclContext *DC, 4526 clang::DeclarationName Name, 4527 llvm::SmallVectorImpl <clang::NamedDecl *> *results) 4528{ 4529 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; 4530 4531 symbol_file_dwarf->SearchDeclContext (DC, Name.getAsString().c_str(), results); 4532} 4533