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