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