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