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