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