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