blob: 27b0aa237d4006fc0d94075c468c5db166ee85bc [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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/Basic/Builtins.h"
18#include "clang/Basic/IdentifierTable.h"
19#include "clang/Basic/LangOptions.h"
20#include "clang/Basic/SourceManager.h"
21#include "clang/Basic/TargetInfo.h"
22#include "clang/Basic/Specifiers.h"
23
24#include "lldb/Core/Module.h"
25#include "lldb/Core/PluginManager.h"
26#include "lldb/Core/RegularExpression.h"
27#include "lldb/Core/Scalar.h"
28#include "lldb/Core/Section.h"
29#include "lldb/Core/Timer.h"
30#include "lldb/Core/Value.h"
31
32#include "lldb/Symbol/Block.h"
33#include "lldb/Symbol/CompileUnit.h"
34#include "lldb/Symbol/LineTable.h"
35#include "lldb/Symbol/ObjectFile.h"
36#include "lldb/Symbol/SymbolVendor.h"
37#include "lldb/Symbol/VariableList.h"
38
39#include "DWARFCompileUnit.h"
40#include "DWARFDebugAbbrev.h"
41#include "DWARFDebugAranges.h"
42#include "DWARFDebugInfo.h"
43#include "DWARFDebugInfoEntry.h"
44#include "DWARFDebugLine.h"
45#include "DWARFDebugPubnames.h"
46#include "DWARFDebugRanges.h"
47#include "DWARFDIECollection.h"
48#include "DWARFFormValue.h"
49#include "DWARFLocationList.h"
50#include "LogChannelDWARF.h"
51
52#include <map>
53
54#define DIE_IS_BEING_PARSED ((void*)1)
55
56using namespace lldb;
57using namespace lldb_private;
58
59
60static const ConstString&
61GetSectionNameDebugInfo()
62{
63 static const ConstString g_sect_name("__debug_info");
64 return g_sect_name;
65}
66
67static const ConstString&
68GetSectionNameDebugAbbrev()
69{
70 static const ConstString g_sect_name ("__debug_abbrev");
71 return g_sect_name;
72}
73
74static const ConstString&
75GetSectionNameDebugAranges()
76{
77 static const ConstString g_sect_name ("__debug_aranges");
78 return g_sect_name;
79}
80
81static const ConstString&
82GetSectionNameDebugFrame()
83{
84 static const ConstString g_sect_name ("__debug_frame");
85 return g_sect_name;
86}
87
88static const ConstString&
89GetSectionNameDebugLine()
90{
91 static const ConstString g_sect_name ("__debug_line");
92 return g_sect_name;
93}
94
95static const ConstString&
96GetSectionNameDebugLoc()
97{
98 static const ConstString g_sect_name ("__debug_loc");
99 return g_sect_name;
100}
101
102static const ConstString&
103GetSectionNameDebugMacInfo()
104{
105 static const ConstString g_sect_name ("__debug_macinfo");
106 return g_sect_name;
107}
108
109static const ConstString&
110GetSectionNameDebugPubNames()
111{
112 static const ConstString g_sect_name ("__debug_pubnames");
113 return g_sect_name;
114}
115
116static const ConstString&
117GetSectionNameDebugPubTypes()
118{
119 static const ConstString g_sect_name ("__debug_pubtypes");
120 return g_sect_name;
121}
122
123static const ConstString&
124GetSectionNameDebugRanges()
125{
126 static const ConstString g_sect_name ("__debug_ranges");
127 return g_sect_name;
128}
129
130static const ConstString&
131GetSectionNameDebugStr()
132{
133 static const ConstString g_sect_name ("__debug_str");
134 return g_sect_name;
135}
136
137static uint32_t
138DwarfToClangAccessibility (uint32_t dwarf_accessibility)
139{
140 switch (dwarf_accessibility)
141 {
142 case DW_ACCESS_public:
143 return clang::AS_public;
144 case DW_ACCESS_private:
145 return clang::AS_private;
146 case DW_ACCESS_protected:
147 return clang::AS_protected;
148 default:
149 return clang::AS_none;
150 }
151}
152
153void
154SymbolFileDWARF::Initialize()
155{
156 LogChannelDWARF::Initialize();
157 PluginManager::RegisterPlugin (GetPluginNameStatic(),
158 GetPluginDescriptionStatic(),
159 CreateInstance);
160}
161
162void
163SymbolFileDWARF::Terminate()
164{
165 PluginManager::UnregisterPlugin (CreateInstance);
166 LogChannelDWARF::Initialize();
167}
168
169
170const char *
171SymbolFileDWARF::GetPluginNameStatic()
172{
173 return "symbol-file.dwarf2";
174}
175
176const char *
177SymbolFileDWARF::GetPluginDescriptionStatic()
178{
179 return "DWARF and DWARF3 debug symbol file reader.";
180}
181
182
183SymbolFile*
184SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
185{
186 return new SymbolFileDWARF(obj_file);
187}
188
189//----------------------------------------------------------------------
190// Gets the first parent that is a lexical block, function or inlined
191// subroutine, or compile unit.
192//----------------------------------------------------------------------
193static const DWARFDebugInfoEntry *
194GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
195{
196 const DWARFDebugInfoEntry *die;
197 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
198 {
199 dw_tag_t tag = die->Tag();
200
201 switch (tag)
202 {
203 case DW_TAG_compile_unit:
204 case DW_TAG_subprogram:
205 case DW_TAG_inlined_subroutine:
206 case DW_TAG_lexical_block:
207 return die;
208 }
209 }
210 return NULL;
211}
212
213
214SymbolFileDWARF::SymbolFileDWARF(ObjectFile* ofile) :
215 SymbolFile(ofile),
216 m_flags(),
217 m_data_debug_abbrev(),
218 m_data_debug_aranges(),
219 m_data_debug_frame(),
220 m_data_debug_info(),
221 m_data_debug_line(),
222 m_data_debug_loc(),
223 m_data_debug_macinfo(),
224 m_data_debug_pubnames(),
225 m_data_debug_pubtypes(),
226 m_data_debug_ranges(),
227 m_data_debug_str(),
228 m_abbr(),
229 m_aranges(),
230 m_info(),
231 m_line(),
232 m_name_to_function_die(),
233 m_name_to_inlined_die(),
234 m_name_to_global_die(),
235 m_name_to_type_die(),
236 m_indexed(false),
237// m_pubnames(),
238// m_pubtypes(),
239// m_pubbasetypes(),
240 m_ranges()//,
241// m_type_fixups(),
242// m_indirect_fixups()
243{
244}
245
246SymbolFileDWARF::~SymbolFileDWARF()
247{
248}
249
250bool
251SymbolFileDWARF::SupportedVersion(uint16_t version)
252{
253 return version == 2 || version == 3;
254}
255
256uint32_t
257SymbolFileDWARF::GetAbilities ()
258{
259 uint32_t abilities = 0;
260 if (m_obj_file != NULL)
261 {
262 const Section* section = NULL;
263 const SectionList *section_list = m_obj_file->GetSectionList();
264 if (section_list == NULL)
265 return 0;
266
267 uint64_t debug_abbrev_file_size = 0;
268 uint64_t debug_aranges_file_size = 0;
269 uint64_t debug_frame_file_size = 0;
270 uint64_t debug_info_file_size = 0;
271 uint64_t debug_line_file_size = 0;
272 uint64_t debug_loc_file_size = 0;
273 uint64_t debug_macinfo_file_size = 0;
274 uint64_t debug_pubnames_file_size = 0;
275 uint64_t debug_pubtypes_file_size = 0;
276 uint64_t debug_ranges_file_size = 0;
277 uint64_t debug_str_file_size = 0;
278
279 static ConstString g_dwarf_section_name ("__DWARF");
280
281 section = section_list->FindSectionByName(g_dwarf_section_name).get();
282
283 if (section)
284 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
285
286 section = section_list->FindSectionByName (GetSectionNameDebugInfo()).get();
287 if (section != NULL)
288 {
289 debug_info_file_size = section->GetByteSize();
290
291 section = section_list->FindSectionByName (GetSectionNameDebugAbbrev()).get();
292 if (section)
293 debug_abbrev_file_size = section->GetByteSize();
294 else
295 m_flags.Set (flagsGotDebugAbbrevData);
296
297 section = section_list->FindSectionByName (GetSectionNameDebugAranges()).get();
298 if (section)
299 debug_aranges_file_size = section->GetByteSize();
300 else
301 m_flags.Set (flagsGotDebugArangesData);
302
303 section = section_list->FindSectionByName (GetSectionNameDebugFrame()).get();
304 if (section)
305 debug_frame_file_size = section->GetByteSize();
306 else
307 m_flags.Set (flagsGotDebugFrameData);
308
309 section = section_list->FindSectionByName (GetSectionNameDebugLine()).get();
310 if (section)
311 debug_line_file_size = section->GetByteSize();
312 else
313 m_flags.Set (flagsGotDebugLineData);
314
315 section = section_list->FindSectionByName (GetSectionNameDebugLoc()).get();
316 if (section)
317 debug_loc_file_size = section->GetByteSize();
318 else
319 m_flags.Set (flagsGotDebugLocData);
320
321 section = section_list->FindSectionByName (GetSectionNameDebugMacInfo()).get();
322 if (section)
323 debug_macinfo_file_size = section->GetByteSize();
324 else
325 m_flags.Set (flagsGotDebugMacInfoData);
326
327 section = section_list->FindSectionByName (GetSectionNameDebugPubNames()).get();
328 if (section)
329 debug_pubnames_file_size = section->GetByteSize();
330 else
331 m_flags.Set (flagsGotDebugPubNamesData);
332
333 section = section_list->FindSectionByName (GetSectionNameDebugPubTypes()).get();
334 if (section)
335 debug_pubtypes_file_size = section->GetByteSize();
336 else
337 m_flags.Set (flagsGotDebugPubTypesData);
338
339 section = section_list->FindSectionByName (GetSectionNameDebugRanges()).get();
340 if (section)
341 debug_ranges_file_size = section->GetByteSize();
342 else
343 m_flags.Set (flagsGotDebugRangesData);
344
345 section = section_list->FindSectionByName (GetSectionNameDebugStr()).get();
346 if (section)
347 debug_str_file_size = section->GetByteSize();
348 else
349 m_flags.Set (flagsGotDebugStrData);
350 }
351
352 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
353 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
354
355 if (debug_line_file_size > 0)
356 abilities |= LineTables;
357
358 if (debug_aranges_file_size > 0)
359 abilities |= AddressAcceleratorTable;
360
361 if (debug_pubnames_file_size > 0)
362 abilities |= FunctionAcceleratorTable;
363
364 if (debug_pubtypes_file_size > 0)
365 abilities |= TypeAcceleratorTable;
366
367 if (debug_macinfo_file_size > 0)
368 abilities |= MacroInformation;
369
370 if (debug_frame_file_size > 0)
371 abilities |= CallFrameInformation;
372 }
373 return abilities;
374}
375
376const DataExtractor&
377SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, const ConstString &section_name, DataExtractor &data)
378{
379 if (m_flags.IsClear (got_flag))
380 {
381 m_flags.Set (got_flag);
382 const SectionList *section_list = m_obj_file->GetSectionList();
383 if (section_list)
384 {
385 Section *section = section_list->FindSectionByName (section_name).get();
386 if (section )
387 {
388 // See if we memory mapped the DWARF segment?
389 if (m_dwarf_data.GetByteSize())
390 {
391 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
392 }
393 else
394 {
395 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
396 data.Clear();
397 }
398 }
399 }
400 }
401 return data;
402}
403
404const DataExtractor&
405SymbolFileDWARF::get_debug_abbrev_data()
406{
407 return GetCachedSectionData (flagsGotDebugAbbrevData, GetSectionNameDebugAbbrev(), m_data_debug_abbrev);
408}
409
410const DataExtractor&
411SymbolFileDWARF::get_debug_aranges_data()
412{
413 return GetCachedSectionData (flagsGotDebugArangesData, GetSectionNameDebugAranges(), m_data_debug_aranges);
414}
415
416const DataExtractor&
417SymbolFileDWARF::get_debug_frame_data()
418{
419 return GetCachedSectionData (flagsGotDebugFrameData, GetSectionNameDebugFrame(), m_data_debug_frame);
420}
421
422const DataExtractor&
423SymbolFileDWARF::get_debug_info_data()
424{
425 return GetCachedSectionData (flagsGotDebugInfoData, GetSectionNameDebugInfo(), m_data_debug_info);
426}
427
428const DataExtractor&
429SymbolFileDWARF::get_debug_line_data()
430{
431 return GetCachedSectionData (flagsGotDebugLineData, GetSectionNameDebugLine(), m_data_debug_line);
432}
433
434const DataExtractor&
435SymbolFileDWARF::get_debug_loc_data()
436{
437 return GetCachedSectionData (flagsGotDebugLocData, GetSectionNameDebugLoc(), m_data_debug_loc);
438}
439
440const DataExtractor&
441SymbolFileDWARF::get_debug_macinfo_data()
442{
443 return GetCachedSectionData (flagsGotDebugMacInfoData, GetSectionNameDebugMacInfo(), m_data_debug_macinfo);
444}
445
446const DataExtractor&
447SymbolFileDWARF::get_debug_pubnames_data()
448{
449 return GetCachedSectionData (flagsGotDebugPubNamesData, GetSectionNameDebugPubNames(), m_data_debug_pubnames);
450}
451
452const DataExtractor&
453SymbolFileDWARF::get_debug_pubtypes_data()
454{
455 return GetCachedSectionData (flagsGotDebugPubTypesData, GetSectionNameDebugPubTypes(), m_data_debug_pubtypes);
456}
457
458const DataExtractor&
459SymbolFileDWARF::get_debug_ranges_data()
460{
461 return GetCachedSectionData (flagsGotDebugRangesData, GetSectionNameDebugRanges(), m_data_debug_ranges);
462}
463
464const DataExtractor&
465SymbolFileDWARF::get_debug_str_data()
466{
467 return GetCachedSectionData (flagsGotDebugStrData, GetSectionNameDebugStr(), m_data_debug_str);
468}
469
470
471DWARFDebugAbbrev*
472SymbolFileDWARF::DebugAbbrev()
473{
474 if (m_abbr.get() == NULL)
475 {
476 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
477 if (debug_abbrev_data.GetByteSize() > 0)
478 {
479 m_abbr.reset(new DWARFDebugAbbrev());
480 if (m_abbr.get())
481 m_abbr->Parse(debug_abbrev_data);
482 }
483 }
484 return m_abbr.get();
485}
486
487const DWARFDebugAbbrev*
488SymbolFileDWARF::DebugAbbrev() const
489{
490 return m_abbr.get();
491}
492
493DWARFDebugAranges*
494SymbolFileDWARF::DebugAranges()
495{
496 if (m_aranges.get() == NULL)
497 {
498 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
499 m_aranges.reset(new DWARFDebugAranges());
500 if (m_aranges.get())
501 {
502 const DataExtractor &debug_aranges_data = get_debug_aranges_data();
503 if (debug_aranges_data.GetByteSize() > 0)
504 m_aranges->Extract(debug_aranges_data);
505 else
506 m_aranges->Generate(this);
507 }
508 }
509 return m_aranges.get();
510}
511
512const DWARFDebugAranges*
513SymbolFileDWARF::DebugAranges() const
514{
515 return m_aranges.get();
516}
517
518
519DWARFDebugInfo*
520SymbolFileDWARF::DebugInfo()
521{
522 if (m_info.get() == NULL)
523 {
524 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
525 if (get_debug_info_data().GetByteSize() > 0)
526 {
527 m_info.reset(new DWARFDebugInfo());
528 if (m_info.get())
529 {
530 m_info->SetDwarfData(this);
531 }
532 }
533 }
534 return m_info.get();
535}
536
537const DWARFDebugInfo*
538SymbolFileDWARF::DebugInfo() const
539{
540 return m_info.get();
541}
542
543//DWARFDebugLine*
544//SymbolFileDWARF::DebugLine()
545//{
546// if (m_line.get() == NULL)
547// {
548// Timer scoped_timer(__PRETTY_FUNCTION__);
549// const DataExtractor &debug_line_data = debug_line();
550// if (debug_line_data.GetByteSize() > 0)
551// {
552// m_line.reset(new DWARFDebugLine());
553// if (m_line.get())
554// m_line->Parse(debug_line_data);
555// }
556// }
557// return m_line.get();
558//}
559//
560//const DWARFDebugLine*
561//SymbolFileDWARF::DebugLine() const
562//{
563// return m_line.get();
564//}
565
566
567DWARFCompileUnit*
568SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
569{
570 DWARFDebugInfo* info = DebugInfo();
571 if (info)
572 return info->GetCompileUnit(cu_uid).get();
573 return NULL;
574}
575
576//DWARFCompileUnit*
577//SymbolFileDWARF::GetNextUnparsedDWARFCompileUnit(DWARFCompileUnit* prev_cu)
578//{
579// DWARFCompileUnit* cu = NULL;
580// DWARFDebugInfo* info = DebugInfo();
581// if (info)
582// {
583// uint32_t cu_idx = 0;
584// if (prev_cu != NULL)
585// {
586// // Find the index of the previus DWARF compile unit if one was provided
587// while ((cu = info->GetCompileUnitAtIndex(cu_idx)) != NULL)
588// {
589// ++cu_idx;
590// if (cu == prev_cu)
591// break;
592// }
593// }
594//
595// // Now find the next unparsed DWARF compile unit. We do this by checking the
596// // user data in the DWARFCompileUnit class that starts as NULL, and eventually
597// // holds a pointer to the CompileUnit that was created for it after it has
598// // been parsed.
599// while ((cu = info->GetCompileUnitAtIndex(cu_idx)) != NULL)
600// {
601// if (cu->GetUserData() == NULL)
602// break;
603// }
604// }
605// return cu;
606//}
607
608DWARFDebugRanges*
609SymbolFileDWARF::DebugRanges()
610{
611 if (m_ranges.get() == NULL)
612 {
613 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
614 if (get_debug_ranges_data().GetByteSize() > 0)
615 {
616 m_ranges.reset(new DWARFDebugRanges());
617 if (m_ranges.get())
618 m_ranges->Extract(this);
619 }
620 }
621 return m_ranges.get();
622}
623
624const DWARFDebugRanges*
625SymbolFileDWARF::DebugRanges() const
626{
627 return m_ranges.get();
628}
629//
630//DWARFDebugPubnames*
631//SymbolFileDWARF::DebugPubnames()
632//{
633// if (m_pubnames.get() == NULL)
634// {
635// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
636// const DataExtractor &debug_pubnames_data = get_debug_pubnames_data();
637// if (debug_pubnames_data.GetByteSize() > 0)
638// {
639// // Pass false to indicate this is a pubnames section
640// m_pubnames.reset(new DWARFDebugPubnames());
641// if (m_pubnames.get())
642// {
643// // "m_pubnames->GeneratePubnames" is costly, but needed for global variables
644// m_pubnames->GeneratePubnames(this);
645//
646//#if 0
647// StreamFile s(stdout);
648// s.Printf (".debug_pubnames for %s/%s:\n",
649// m_obj_file->GetModule()->GetFileSpec().GetDirectory().AsCString(),
650// m_obj_file->GetModule()->GetFileSpec().GetFilename().AsCString());
651// m_pubnames->Dump (&s);
652//#endif
653// // "m_pubnames->Extract" is quicker, but the pubnames don't always contain what we need.
654// //m_pubnames->Extract(debug_pubnames_data);
655// }
656// }
657// }
658// return m_pubnames.get();
659//}
660//
661//const DWARFDebugPubnames*
662//SymbolFileDWARF::DebugPubnames() const
663//{
664// return m_pubnames.get();
665//}
666
667//DWARFDebugPubnames*
668//SymbolFileDWARF::DebugPubBaseTypes()
669//{
670// if (m_pubbasetypes.get() == NULL)
671// {
672// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
673// // Pass false to indicate this is a pubnames section
674// m_pubbasetypes.reset(new DWARFDebugPubnames());
675// if (m_pubbasetypes.get())
676// m_pubbasetypes->GeneratePubBaseTypes(this);
677// }
678// return m_pubbasetypes.get();
679//}
680//
681//const DWARFDebugPubnames*
682//SymbolFileDWARF::DebugPubBaseTypes() const
683//{
684// return m_pubbasetypes.get();
685//}
686//
687//const DWARFDebugPubnames*
688//SymbolFileDWARF::DebugPubtypes() const
689//{
690// return m_pubtypes.get();
691//}
692//
693//DWARFDebugPubnames*
694//SymbolFileDWARF::DebugPubtypes()
695//{
696// if (m_pubtypes.get() == NULL)
697// {
698// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
699// const DataExtractor &debug_pubtypes_data = get_debug_pubtypes_data();
700// if (debug_pubtypes_data.GetByteSize() > 0)
701// {
702// // Pass false to indicate this is a pubnames section
703// m_pubtypes.reset(new DWARFDebugPubnames());
704// if (m_pubtypes.get())
705// m_pubtypes->Extract(debug_pubtypes_data);
706// }
707// }
708// return m_pubtypes.get();
709//}
710//
711
712bool
713SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp)
714{
715 if (cu != NULL)
716 {
717 const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly ();
718 if (cu_die)
719 {
720 const char * cu_die_name = cu_die->GetName(this, cu);
721 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL);
722 Language::Type language = (Language::Type)cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_language, 0);
723 if (cu_die_name)
724 {
725 if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0])
726 {
727 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, cu_die_name, cu->GetOffset(), language));
728 }
729 else
730 {
731 std::string fullpath(cu_comp_dir);
732 if (*fullpath.rbegin() != '/')
733 fullpath += '/';
734 fullpath += cu_die_name;
735
736 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, fullpath.c_str(), cu->GetOffset(), language));
737 }
738
739 if (compile_unit_sp.get())
740 {
741 cu->SetUserData(compile_unit_sp.get());
742 return true;
743 }
744 }
745 }
746 }
747 return false;
748}
749
750#if defined LLDB_SYMBOL_FILE_DWARF_SHRINK_TEST
751
752void
753SymbolFileDWARF::ShrinkDSYM(CompileUnit *dc_cu, DWARFCompileUnit *dw_cu, const FileSpec& cu_fspec, const FileSpec& base_types_fspec, FSToDIES& fs_to_dies, const DWARFDebugInfoEntry *die)
754{
755 while (die != NULL)
756 {
757 dw_tag_t tag = die->Tag();
758
759 switch (tag)
760 {
761 case DW_TAG_base_type:
762 // Put all base types into the base type compile unit
763 fs_to_dies[base_types_fspec].Insert(die);
764 break;
765
766 default:
767 {
768 uint32_t decl_file = die->GetAttributeValueAsUnsigned(this, dw_cu, DW_AT_decl_file, 0);
769 if (decl_file)
770 {
771 fs_to_dies[dc_cu->GetSupportFiles().GetFileSpecAtIndex(decl_file)].Insert(die);
772 }
773 else
774 {
775 // add this to the current compile unit
776 fs_to_dies[cu_fspec].Insert(die);
777 }
778 }
779 break;
780 }
781
782 die = die->GetSibling();
783 }
784}
785
786
787
788#endif
789
790uint32_t
791SymbolFileDWARF::GetNumCompileUnits()
792{
793 DWARFDebugInfo* info = DebugInfo();
794 if (info)
795 {
796#if defined LLDB_SYMBOL_FILE_DWARF_SHRINK_TEST
797 uint32_t cu_idx;
798 FSToDIES fs_to_dies;
799
800 FileSpec base_type_fspec("DW_TAG_base_type");
801 const uint32_t num_comp_units = info->GetNumCompileUnits();
802
803 for (cu_idx=0; cu_idx < num_comp_units; ++cu_idx)
804 {
805 DWARFCompileUnit* cu = info->GetCompileUnitAtIndex(cu_idx);
806 if (cu != NULL)
807 {
808 const DWARFDebugInfoEntry *cu_die = cu->DIE();
809 if (cu_die)
810 {
811 CompUnitSP dc_cu_sp;
812 ParseCompileUnit(cu, dc_cu_sp);
813 if (dc_cu_sp.get())
814 {
815 FileSpec cu_fspec(*dc_cu_sp.get());
816
817 ShrinkDSYM(dc_cu_sp.get(), cu, cu_fspec, base_type_fspec, fs_to_dies, cu->DIE()->GetFirstChild());
818 }
819 }
820 }
821 }
822
823 Stream strm(stdout);
824 FSToDIES::const_iterator pos, end = fs_to_dies.end();
825 for (pos = fs_to_dies.begin(); pos != end; ++pos)
826 {
827 strm << "\n\nMinimal Compile Unit: " << pos->first << ":\n";
828 const DWARFDIECollection& dies = pos->second;
829 dies.Dump(strm, NULL);
830 }
831 return num_comp_units;
832#else
833 return info->GetNumCompileUnits();
834#endif
835 }
836 return 0;
837}
838
839CompUnitSP
840SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
841{
842 CompUnitSP comp_unit;
843 DWARFDebugInfo* info = DebugInfo();
844 if (info)
845 {
846 DWARFCompileUnit* cu = info->GetCompileUnitAtIndex(cu_idx);
847 if (cu != NULL)
848 {
849 // Our symbol vendor shouldn't be asking us to add a compile unit that
850 // has already been added to it, which this DWARF plug-in knows as it
851 // stores the lldb compile unit (CompileUnit) pointer in each
852 // DWARFCompileUnit object when it gets added.
853 assert(cu->GetUserData() == NULL);
854 ParseCompileUnit(cu, comp_unit);
855 }
856 }
857 return comp_unit;
858}
859
860static void
861AddRangesToBlock
862(
863 BlockList& blocks,
864 lldb::user_id_t blockID,
865 DWARFDebugRanges::RangeList& ranges,
866 addr_t block_base_addr
867)
868{
869 ranges.SubtractOffset (block_base_addr);
870 size_t range_idx = 0;
871 const DWARFDebugRanges::Range *debug_range;
872 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
873 {
874 blocks.AddRange(blockID, debug_range->begin_offset, debug_range->end_offset);
875 }
876}
877
878
879Function *
880SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
881{
882 DWARFDebugRanges::RangeList func_ranges;
883 const char *name = NULL;
884 const char *mangled = NULL;
885 int decl_file = 0;
886 int decl_line = 0;
887 int decl_column = 0;
888 int call_file = 0;
889 int call_line = 0;
890 int call_column = 0;
891 DWARFExpression frame_base;
892
893 // Parse the function prototype as a type that can then be added to concrete function instance
894 ParseTypes (sc, dwarf_cu, die, false, false);
895 //FixupTypes();
896
897 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
898 {
899 // Union of all ranges in the function DIE (if the function is discontiguous)
900 AddressRange func_range;
901 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
902 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
903 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
904 {
905 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
906 if (func_range.GetBaseAddress().IsValid())
907 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
908 }
909
910 if (func_range.GetBaseAddress().IsValid())
911 {
912 Mangled func_name;
913 if (mangled)
914 func_name.SetValue(mangled, true);
915 else if (name)
916 func_name.SetValue(name, false);
917
918 FunctionSP func_sp;
919 std::auto_ptr<Declaration> decl_ap;
920 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
921 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column));
922
923 Type *func_type = NULL;
924
925 if (die->GetUserData() != DIE_IS_BEING_PARSED)
926 func_type = (Type*)die->GetUserData();
927
928 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
929
930 func_range.GetBaseAddress().ResolveLinkedAddress();
931
932 func_sp.reset(new Function (sc.comp_unit,
933 die->GetOffset(), // UserID is the DIE offset
934 die->GetOffset(),
935 func_name,
936 func_type,
937 func_range)); // first address range
938
939 if (func_sp.get() != NULL)
940 {
941 func_sp->GetFrameBaseExpression() = frame_base;
942 sc.comp_unit->AddFunction(func_sp);
943 return func_sp.get();
944 }
945 }
946 }
947 return NULL;
948}
949
950size_t
951SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
952{
953 assert (sc.comp_unit);
954 size_t functions_added = 0;
955 const DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
956 if (dwarf_cu)
957 {
958 DWARFDIECollection function_dies;
959 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
960 size_t func_idx;
961 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
962 {
963 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
964 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
965 {
966 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
967 ++functions_added;
968 }
969 }
970 //FixupTypes();
971 }
972 return functions_added;
973}
974
975bool
976SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
977{
978 assert (sc.comp_unit);
979 DWARFCompileUnit* cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
980 assert (cu);
981 const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly();
982
983 if (cu_die)
984 {
985 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL);
986 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
987
988 // All file indexes in DWARF are one based and a file of index zero is
989 // supposed to be the compile unit itself.
990 support_files.Append (*sc.comp_unit);
991
992 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
993 }
994 return false;
995}
996
997struct ParseDWARFLineTableCallbackInfo
998{
999 LineTable* line_table;
1000 const SectionList *section_list;
1001 lldb::addr_t prev_sect_file_base_addr;
1002 lldb::addr_t curr_sect_file_base_addr;
1003 bool is_oso_for_debug_map;
1004 bool prev_in_final_executable;
1005 DWARFDebugLine::Row prev_row;
1006 SectionSP prev_section_sp;
1007 SectionSP curr_section_sp;
1008};
1009
1010//----------------------------------------------------------------------
1011// ParseStatementTableCallback
1012//----------------------------------------------------------------------
1013static void
1014ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
1015{
1016 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
1017 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
1018 {
1019 // Just started parsing the line table
1020 }
1021 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
1022 {
1023 // Done parsing line table, nothing to do for the cleanup
1024 }
1025 else
1026 {
1027 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
1028 // We have a new row, lets append it
1029
1030 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
1031 {
1032 info->prev_section_sp = info->curr_section_sp;
1033 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
1034 // If this is an end sequence entry, then we subtract one from the
1035 // address to make sure we get an address that is not the end of
1036 // a section.
1037 if (state.end_sequence && state.address != 0)
1038 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
1039 else
1040 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
1041
1042 if (info->curr_section_sp.get())
1043 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
1044 else
1045 info->curr_sect_file_base_addr = 0;
1046 }
1047 if (info->curr_section_sp.get())
1048 {
1049 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
1050 // Check for the fancy section magic to determine if we
1051
1052 if (info->is_oso_for_debug_map)
1053 {
1054 // When this is a debug map object file that contains DWARF
1055 // (referenced from an N_OSO debug map nlist entry) we will have
1056 // a file address in the file range for our section from the
1057 // original .o file, and a load address in the executable that
1058 // contains the debug map.
1059 //
1060 // If the sections for the file range and load range are
1061 // different, we have a remapped section for the function and
1062 // this address is resolved. If they are the same, then the
1063 // function for this address didn't make it into the final
1064 // executable.
1065 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
1066
1067 // If we are doing DWARF with debug map, then we need to carefully
1068 // add each line table entry as there may be gaps as functions
1069 // get moved around or removed.
1070 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
1071 {
1072 if (info->prev_in_final_executable)
1073 {
1074 bool terminate_previous_entry = false;
1075 if (!curr_in_final_executable)
1076 {
1077 // Check for the case where the previous line entry
1078 // in a function made it into the final executable,
1079 // yet the current line entry falls in a function
1080 // that didn't. The line table used to be contiguous
1081 // through this address range but now it isn't. We
1082 // need to terminate the previous line entry so
1083 // that we can reconstruct the line range correctly
1084 // for it and to keep the line table correct.
1085 terminate_previous_entry = true;
1086 }
1087 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
1088 {
1089 // Check for cases where the line entries used to be
1090 // contiguous address ranges, but now they aren't.
1091 // This can happen when order files specify the
1092 // ordering of the functions.
1093 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
1094 Section *curr_sect = info->curr_section_sp.get();
1095 Section *prev_sect = info->prev_section_sp.get();
1096 assert (curr_sect->GetLinkedSection());
1097 assert (prev_sect->GetLinkedSection());
1098 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
1099 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
1100 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
1101 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
1102 if (object_file_addr_delta != linked_file_addr_delta)
1103 terminate_previous_entry = true;
1104 }
1105
1106 if (terminate_previous_entry)
1107 {
1108 line_table->InsertLineEntry (info->prev_section_sp,
1109 state.address - info->prev_sect_file_base_addr,
1110 info->prev_row.line,
1111 info->prev_row.column,
1112 info->prev_row.file,
1113 false, // is_stmt
1114 false, // basic_block
1115 false, // state.prologue_end
1116 false, // state.epilogue_begin
1117 true); // end_sequence);
1118 }
1119 }
1120 }
1121
1122 if (curr_in_final_executable)
1123 {
1124 line_table->InsertLineEntry (info->curr_section_sp,
1125 curr_line_section_offset,
1126 state.line,
1127 state.column,
1128 state.file,
1129 state.is_stmt,
1130 state.basic_block,
1131 state.prologue_end,
1132 state.epilogue_begin,
1133 state.end_sequence);
1134 info->prev_section_sp = info->curr_section_sp;
1135 }
1136 else
1137 {
1138 // If the current address didn't make it into the final
1139 // executable, the current section will be the __text
1140 // segment in the .o file, so we need to clear this so
1141 // we can catch the next function that did make it into
1142 // the final executable.
1143 info->prev_section_sp.reset();
1144 info->curr_section_sp.reset();
1145 }
1146
1147 info->prev_in_final_executable = curr_in_final_executable;
1148 }
1149 else
1150 {
1151 // We are not in an object file that contains DWARF for an
1152 // N_OSO, this is just a normal DWARF file. The DWARF spec
1153 // guarantees that the addresses will be in increasing order
1154 // so, since we store line tables in file address order, we
1155 // can always just append the line entry without needing to
1156 // search for the correct insertion point (we don't need to
1157 // use LineEntry::InsertLineEntry()).
1158 line_table->AppendLineEntry (info->curr_section_sp,
1159 curr_line_section_offset,
1160 state.line,
1161 state.column,
1162 state.file,
1163 state.is_stmt,
1164 state.basic_block,
1165 state.prologue_end,
1166 state.epilogue_begin,
1167 state.end_sequence);
1168 }
1169 }
1170
1171 info->prev_row = state;
1172 }
1173}
1174
1175bool
1176SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
1177{
1178 assert (sc.comp_unit);
1179 if (sc.comp_unit->GetLineTable() != NULL)
1180 return true;
1181
1182 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
1183 if (dwarf_cu)
1184 {
1185 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
1186 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
1187 if (cu_line_offset != DW_INVALID_OFFSET)
1188 {
1189 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
1190 if (line_table_ap.get())
1191 {
1192 ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_flags.IsSet (flagsDWARFIsOSOForDebugMap), false};
1193 uint32_t offset = cu_line_offset;
1194 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
1195 sc.comp_unit->SetLineTable(line_table_ap.release());
1196 return true;
1197 }
1198 }
1199 }
1200 return false;
1201}
1202
1203size_t
1204SymbolFileDWARF::ParseFunctionBlocks
1205(
1206 const SymbolContext& sc,
1207 lldb::user_id_t parentBlockID,
1208 const DWARFCompileUnit* dwarf_cu,
1209 const DWARFDebugInfoEntry *die,
1210 addr_t subprogram_low_pc,
1211 bool parse_siblings,
1212 bool parse_children
1213)
1214{
1215 size_t blocks_added = 0;
1216 while (die != NULL)
1217 {
1218 dw_tag_t tag = die->Tag();
1219
1220 switch (tag)
1221 {
1222 case DW_TAG_subprogram:
1223 case DW_TAG_inlined_subroutine:
1224 case DW_TAG_lexical_block:
1225 {
1226 DWARFDebugRanges::RangeList ranges;
1227 const char *name = NULL;
1228 const char *mangled_name = NULL;
1229 BlockList& blocks = sc.function->GetBlocks(false);
1230
1231 lldb::user_id_t blockID = blocks.AddChild(parentBlockID, die->GetOffset());
1232 int decl_file = 0;
1233 int decl_line = 0;
1234 int decl_column = 0;
1235 int call_file = 0;
1236 int call_line = 0;
1237 int call_column = 0;
1238 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled_name, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column))
1239 {
1240 if (tag == DW_TAG_subprogram)
1241 {
1242 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1243 subprogram_low_pc = ranges.LowestAddress(0);
1244 }
1245
1246 AddRangesToBlock (blocks, blockID, ranges, subprogram_low_pc);
1247
1248 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1249 {
1250 std::auto_ptr<Declaration> decl_ap;
1251 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
1252 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column));
1253
1254 std::auto_ptr<Declaration> call_ap;
1255 if (call_file != 0 || call_line != 0 || call_column != 0)
1256 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), call_line, call_column));
1257
1258 blocks.SetInlinedFunctionInfo(blockID, name, mangled_name, decl_ap.get(), call_ap.get());
1259 }
1260
1261 ++blocks_added;
1262
1263 if (parse_children && die->HasChildren())
1264 {
1265 blocks_added += ParseFunctionBlocks(sc, blockID, dwarf_cu, die->GetFirstChild(), subprogram_low_pc, true, true);
1266 }
1267 }
1268 }
1269 break;
1270 default:
1271 break;
1272 }
1273
1274 if (parse_siblings)
1275 die = die->GetSibling();
1276 else
1277 die = NULL;
1278 }
1279 return blocks_added;
1280}
1281
1282size_t
1283SymbolFileDWARF::ParseChildMembers
1284(
1285 const SymbolContext& sc,
1286 TypeSP& type_sp,
1287 const DWARFCompileUnit* dwarf_cu,
1288 const DWARFDebugInfoEntry *parent_die,
1289 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1290 std::vector<int>& member_accessibilities,
1291 int& default_accessibility,
1292 bool &is_a_class
1293)
1294{
1295 if (parent_die == NULL)
1296 return 0;
1297
1298 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
1299
1300 size_t count = 0;
1301 const DWARFDebugInfoEntry *die;
1302 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1303 {
1304 dw_tag_t tag = die->Tag();
1305
1306 switch (tag)
1307 {
1308 case DW_TAG_member:
1309 {
1310 DWARFDebugInfoEntry::Attributes attributes;
1311 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
1312 if (num_attributes > 0)
1313 {
1314 Declaration decl;
1315 DWARFExpression location;
1316 const char *name = NULL;
1317 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
1318 uint32_t accessibility = clang::AS_none;
1319 off_t member_offset = 0;
1320 size_t byte_size = 0;
1321 size_t bit_offset = 0;
1322 size_t bit_size = 0;
1323 uint32_t i;
1324 for (i=0; i<num_attributes; ++i)
1325 {
1326 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1327 DWARFFormValue form_value;
1328 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1329 {
1330 switch (attr)
1331 {
1332 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1333 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1334 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1335 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1336 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1337 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1338 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1339 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1340 case DW_AT_data_member_location:
1341 if (form_value.BlockData())
1342 {
1343 Value initialValue(0);
1344 Value memberOffset(0);
1345 const DataExtractor& debug_info_data = get_debug_info_data();
1346 uint32_t block_length = form_value.Unsigned();
1347 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1348 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1349 {
1350 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1351 }
1352 }
1353 break;
1354
1355 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility (form_value.Unsigned()); break;
1356 case DW_AT_declaration:
1357 case DW_AT_description:
1358 case DW_AT_mutable:
1359 case DW_AT_visibility:
1360 default:
1361 case DW_AT_sibling:
1362 break;
1363 }
1364 }
1365 }
1366
1367 Type *member_type = ResolveTypeUID(encoding_uid);
1368 assert(member_type);
1369 if (accessibility == clang::AS_none)
1370 accessibility = default_accessibility;
1371 member_accessibilities.push_back(accessibility);
1372
1373 type_list->GetClangASTContext().AddFieldToRecordType (type_sp->GetOpaqueClangQualType(), name, member_type->GetOpaqueClangQualType(), accessibility, bit_size);
1374 }
1375 }
1376 break;
1377
1378 case DW_TAG_subprogram:
1379 {
1380 is_a_class = true;
1381 if (default_accessibility == clang::AS_none)
1382 default_accessibility = clang::AS_private;
1383 // TODO: implement DW_TAG_subprogram type parsing
1384// UserDefTypeChildInfo method_info(die->GetOffset());
1385//
1386// FunctionSP func_sp (sc.comp_unit->FindFunctionByUID (die->GetOffset()));
1387// if (func_sp.get() == NULL)
1388// ParseCompileUnitFunction(sc, dwarf_cu, die);
1389//
1390// method_info.SetEncodingTypeUID(die->GetOffset());
1391// struct_udt->AddMethod(method_info);
1392 }
1393 break;
1394
1395 case DW_TAG_inheritance:
1396 {
1397 is_a_class = true;
1398 if (default_accessibility == clang::AS_none)
1399 default_accessibility = clang::AS_private;
1400 // TODO: implement DW_TAG_inheritance type parsing
1401 DWARFDebugInfoEntry::Attributes attributes;
1402 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
1403 if (num_attributes > 0)
1404 {
1405 Declaration decl;
1406 DWARFExpression location;
1407 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
1408 uint32_t accessibility = default_accessibility;
1409 bool is_virtual = false;
1410 bool is_base_of_class = true;
1411 off_t member_offset = 0;
1412 uint32_t i;
1413 for (i=0; i<num_attributes; ++i)
1414 {
1415 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1416 DWARFFormValue form_value;
1417 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1418 {
1419 switch (attr)
1420 {
1421 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1422 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1423 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1424 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1425 case DW_AT_data_member_location:
1426 if (form_value.BlockData())
1427 {
1428 Value initialValue(0);
1429 Value memberOffset(0);
1430 const DataExtractor& debug_info_data = get_debug_info_data();
1431 uint32_t block_length = form_value.Unsigned();
1432 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1433 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1434 {
1435 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1436 }
1437 }
1438 break;
1439
1440 case DW_AT_accessibility:
1441 accessibility = DwarfToClangAccessibility(form_value.Unsigned());
1442 break;
1443
1444 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1445 default:
1446 case DW_AT_sibling:
1447 break;
1448 }
1449 }
1450 }
1451
1452 Type *base_class_dctype = ResolveTypeUID(encoding_uid);
1453 assert(base_class_dctype);
1454 base_classes.push_back (type_list->GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetOpaqueClangQualType(), accessibility, is_virtual, is_base_of_class));
1455 assert(base_classes.back());
1456 }
1457 }
1458 break;
1459
1460 default:
1461 break;
1462 }
1463 }
1464 return count;
1465}
1466
1467
1468clang::DeclContext*
1469SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1470{
1471 DWARFDebugInfo* debug_info = DebugInfo();
1472 if (debug_info)
1473 {
1474 DWARFCompileUnitSP cu_sp;
1475 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1476 if (die)
1477 return GetClangDeclContextForDIE (cu_sp.get(), die);
1478 }
1479 return NULL;
1480}
1481
1482Type*
1483SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid)
1484{
1485 DWARFDebugInfo* debug_info = DebugInfo();
1486 if (debug_info)
1487 {
1488 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, NULL);
1489 if (type_die != NULL)
1490 {
1491 void *type = type_die->GetUserData();
1492 if (type == NULL)
1493 {
1494 DWARFCompileUnitSP cu_sp;
1495 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1496 if (die != NULL)
1497 {
1498 TypeSP owning_type_sp;
1499 TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, 0, 0));
1500 }
1501 type = type_die->GetUserData();
1502 }
1503 if (type != DIE_IS_BEING_PARSED)
1504 return (Type *)type;
1505 }
1506 }
1507 return NULL;
1508}
1509
1510CompileUnit*
1511SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx)
1512{
1513 // Check if the symbol vendor already knows about this compile unit?
1514 if (cu->GetUserData() == NULL)
1515 {
1516 // The symbol vendor doesn't know about this compile unit, we
1517 // need to parse and add it to the symbol vendor object.
1518 CompUnitSP dc_cu;
1519 ParseCompileUnit(cu, dc_cu);
1520 if (dc_cu.get())
1521 {
1522 // Figure out the compile unit index if we weren't given one
1523 if (cu_idx == UINT_MAX)
1524 DebugInfo()->GetCompileUnit(cu->GetOffset(), &cu_idx);
1525
1526 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
1527 }
1528 }
1529 return (CompileUnit*)cu->GetUserData();
1530}
1531
1532bool
1533SymbolFileDWARF::GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
1534{
1535 sc.Clear();
1536 // Check if the symbol vendor already knows about this compile unit?
1537 sc.module_sp = m_obj_file->GetModule()->GetSP();
1538 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
1539
1540 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1541 if (sc.function == NULL)
1542 sc.function = ParseCompileUnitFunction(sc, cu, func_die);
1543
1544 return sc.function != NULL;
1545}
1546
1547uint32_t
1548SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1549{
1550 Timer scoped_timer(__PRETTY_FUNCTION__,
1551 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1552 so_addr.GetSection(),
1553 so_addr.GetOffset(),
1554 resolve_scope);
1555 uint32_t resolved = 0;
1556 if (resolve_scope & ( eSymbolContextCompUnit |
1557 eSymbolContextFunction |
1558 eSymbolContextBlock |
1559 eSymbolContextLineEntry))
1560 {
1561 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1562
1563 DWARFDebugAranges* debug_aranges = DebugAranges();
1564 DWARFDebugInfo* debug_info = DebugInfo();
1565 if (debug_aranges)
1566 {
1567 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1568 if (cu_offset != DW_INVALID_OFFSET)
1569 {
1570 uint32_t cu_idx;
1571 DWARFCompileUnit* cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1572 if (cu)
1573 {
1574 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1575 assert(sc.comp_unit != NULL);
1576 resolved |= eSymbolContextCompUnit;
1577
1578 if (resolve_scope & eSymbolContextLineEntry)
1579 {
1580 LineTable *line_table = sc.comp_unit->GetLineTable();
1581 if (line_table == NULL)
1582 {
1583 if (ParseCompileUnitLineTable(sc))
1584 line_table = sc.comp_unit->GetLineTable();
1585 }
1586 if (line_table != NULL)
1587 {
1588 if (so_addr.IsLinkedAddress())
1589 {
1590 Address linked_addr (so_addr);
1591 linked_addr.ResolveLinkedAddress();
1592 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1593 {
1594 resolved |= eSymbolContextLineEntry;
1595 }
1596 }
1597 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1598 {
1599 resolved |= eSymbolContextLineEntry;
1600 }
1601 }
1602 }
1603
1604 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1605 {
1606 DWARFDebugInfoEntry *function_die = NULL;
1607 DWARFDebugInfoEntry *block_die = NULL;
1608 if (resolve_scope & eSymbolContextBlock)
1609 {
1610 cu->LookupAddress(file_vm_addr, &function_die, &block_die);
1611 }
1612 else
1613 {
1614 cu->LookupAddress(file_vm_addr, &function_die, NULL);
1615 }
1616
1617 if (function_die != NULL)
1618 {
1619 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1620 if (sc.function == NULL)
1621 sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1622 }
1623
1624 if (sc.function != NULL)
1625 {
1626 resolved |= eSymbolContextFunction;
1627
1628 if (resolve_scope & eSymbolContextBlock)
1629 {
1630 BlockList& blocks = sc.function->GetBlocks(true);
1631
1632 if (block_die != NULL)
1633 sc.block = blocks.GetBlockByID(block_die->GetOffset());
1634 else
1635 sc.block = blocks.GetBlockByID(function_die->GetOffset());
1636 if (sc.block)
1637 resolved |= eSymbolContextBlock;
1638 }
1639 }
1640 }
1641 }
1642 }
1643 }
1644 }
1645 return resolved;
1646}
1647
1648
1649
1650uint32_t
1651SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1652{
1653 const uint32_t prev_size = sc_list.GetSize();
1654 if (resolve_scope & eSymbolContextCompUnit)
1655 {
1656 DWARFDebugInfo* debug_info = DebugInfo();
1657 if (debug_info)
1658 {
1659 uint32_t cu_idx;
1660 DWARFCompileUnit* cu = NULL;
1661
1662 for (cu_idx = 0; (cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
1663 {
1664 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1665 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1666 if (check_inlines || file_spec_matches_cu_file_spec)
1667 {
1668 SymbolContext sc (m_obj_file->GetModule());
1669 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1670 assert(sc.comp_unit != NULL);
1671
1672 uint32_t file_idx = UINT32_MAX;
1673
1674 // If we are looking for inline functions only and we don't
1675 // find it in the support files, we are done.
1676 if (check_inlines)
1677 {
1678 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1679 if (file_idx == UINT32_MAX)
1680 continue;
1681 }
1682
1683 if (line != 0)
1684 {
1685 LineTable *line_table = sc.comp_unit->GetLineTable();
1686
1687 if (line_table != NULL && line != 0)
1688 {
1689 // We will have already looked up the file index if
1690 // we are searching for inline entries.
1691 if (!check_inlines)
1692 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1693
1694 if (file_idx != UINT32_MAX)
1695 {
1696 uint32_t found_line;
1697 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1698 found_line = sc.line_entry.line;
1699
1700 while (line_idx != UINT_MAX)
1701 {
1702 sc.function = NULL;
1703 sc.block = NULL;
1704 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1705 {
1706 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1707 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1708 {
1709 DWARFDebugInfoEntry *function_die = NULL;
1710 DWARFDebugInfoEntry *block_die = NULL;
1711 cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
1712
1713 if (function_die != NULL)
1714 {
1715 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1716 if (sc.function == NULL)
1717 sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1718 }
1719
1720 if (sc.function != NULL)
1721 {
1722 BlockList& blocks = sc.function->GetBlocks(true);
1723
1724 if (block_die != NULL)
1725 sc.block = blocks.GetBlockByID(block_die->GetOffset());
1726 else
1727 sc.block = blocks.GetBlockByID(function_die->GetOffset());
1728 }
1729 }
1730 }
1731
1732 sc_list.Append(sc);
1733 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1734 }
1735 }
1736 }
1737 else if (file_spec_matches_cu_file_spec && !check_inlines)
1738 {
1739 // only append the context if we aren't looking for inline call sites
1740 // by file and line and if the file spec matches that of the compile unit
1741 sc_list.Append(sc);
1742 }
1743 }
1744 else if (file_spec_matches_cu_file_spec && !check_inlines)
1745 {
1746 // only append the context if we aren't looking for inline call sites
1747 // by file and line and if the file spec matches that of the compile unit
1748 sc_list.Append(sc);
1749 }
1750
1751 if (!check_inlines)
1752 break;
1753 }
1754 }
1755 }
1756 }
1757 return sc_list.GetSize() - prev_size;
1758}
1759
1760void
1761SymbolFileDWARF::Index ()
1762{
1763 if (m_indexed)
1764 return;
1765 m_indexed = true;
1766 Timer scoped_timer (__PRETTY_FUNCTION__,
1767 "SymbolFileDWARF::Index (%s)",
1768 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1769
1770 DWARFDebugInfo* debug_info = DebugInfo();
1771 if (debug_info)
1772 {
1773 uint32_t cu_idx = 0;
1774 const uint32_t num_compile_units = GetNumCompileUnits();
1775 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1776 {
1777 DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
1778
1779 bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1;
1780
1781 cu->Index (m_name_to_function_die,
1782 m_name_to_inlined_die,
1783 m_name_to_global_die,
1784 m_name_to_type_die);
1785
1786 // Keep memory down by clearing DIEs if this generate function
1787 // caused them to be parsed
1788 if (clear_dies)
1789 cu->ClearDIEs (true);
1790 }
1791
1792 m_name_to_function_die.Sort();
1793 m_name_to_inlined_die.Sort();
1794 m_name_to_global_die.Sort();
1795 m_name_to_type_die.Sort();
1796 }
1797}
1798
1799uint32_t
1800SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1801{
1802 std::vector<dw_offset_t> die_offsets;
1803
1804 // If we aren't appending the results to this list, then clear the list
1805 if (!append)
1806 variables.Clear();
1807
1808 // Remember how many variables are in the list before we search in case
1809 // we are appending the results to a variable list.
1810 const uint32_t original_size = variables.GetSize();
1811
1812 // Index the DWARF if we haven't already
1813 if (!m_indexed)
1814 Index ();
1815
1816 const UniqueCStringMap<dw_offset_t>::Entry *entry;
1817
1818 for (entry = m_name_to_global_die.FindFirstValueForName (name.AsCString());
1819 entry != NULL;
1820 entry = m_name_to_global_die.FindNextValueForName (name.AsCString(), entry))
1821 {
1822 DWARFCompileUnitSP cu_sp;
1823 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp);
1824 DWARFCompileUnit* cu = cu_sp.get();
1825 if (die)
1826 {
1827 SymbolContext sc;
1828 sc.module_sp = m_obj_file->GetModule()->GetSP();
1829 assert (sc.module_sp);
1830
1831 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
1832 assert(sc.comp_unit != NULL);
1833
1834 ParseVariables(sc, cu_sp.get(), die, false, false, &variables);
1835
1836 if (variables.GetSize() - original_size >= max_matches)
1837 break;
1838 }
1839 }
1840
1841 // Return the number of variable that were appended to the list
1842 return variables.GetSize() - original_size;
1843}
1844
1845uint32_t
1846SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1847{
1848 std::vector<dw_offset_t> die_offsets;
1849
1850 // If we aren't appending the results to this list, then clear the list
1851 if (!append)
1852 variables.Clear();
1853
1854 // Remember how many variables are in the list before we search in case
1855 // we are appending the results to a variable list.
1856 const uint32_t original_size = variables.GetSize();
1857
1858 // Index the DWARF if we haven't already
1859 if (!m_indexed)
1860 Index ();
1861
1862 // Create the pubnames information so we can quickly lookup external symbols by name
1863 const size_t num_entries = m_name_to_global_die.GetSize();
1864 for (size_t i=0; i<num_entries; i++)
1865 {
1866 if (!regex.Execute(m_name_to_global_die.GetCStringAtIndex (i)))
1867 continue;
1868
1869 const dw_offset_t die_offset = *m_name_to_global_die.GetValueAtIndex (i);
1870
1871 DWARFCompileUnitSP cu_sp;
1872 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp);
1873 DWARFCompileUnit* cu = cu_sp.get();
1874 if (die)
1875 {
1876 SymbolContext sc;
1877 sc.module_sp = m_obj_file->GetModule()->GetSP();
1878 assert (sc.module_sp);
1879
1880
1881 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
1882 assert(sc.comp_unit != NULL);
1883
1884 ParseVariables(sc, cu_sp.get(), die, false, false, &variables);
1885
1886 if (variables.GetSize() - original_size >= max_matches)
1887 break;
1888 }
1889 }
1890
1891 // Return the number of variable that were appended to the list
1892 return variables.GetSize() - original_size;
1893}
1894
1895
1896uint32_t
1897SymbolFileDWARF::FindFunctions(const ConstString &name, bool append, SymbolContextList& sc_list)
1898{
1899 Timer scoped_timer (__PRETTY_FUNCTION__,
1900 "SymbolFileDWARF::FindFunctions (name = '%s')",
1901 name.AsCString());
1902
1903 std::vector<dw_offset_t> die_offsets;
1904
1905 // If we aren't appending the results to this list, then clear the list
1906 if (!append)
1907 sc_list.Clear();
1908
1909 // Remember how many sc_list are in the list before we search in case
1910 // we are appending the results to a variable list.
1911 uint32_t original_size = sc_list.GetSize();
1912
1913 // Index the DWARF if we haven't already
1914 if (!m_indexed)
1915 Index ();
1916
1917 const UniqueCStringMap<dw_offset_t>::Entry *entry;
1918
1919 SymbolContext sc;
1920 for (entry = m_name_to_function_die.FindFirstValueForName (name.AsCString());
1921 entry != NULL;
1922 entry = m_name_to_function_die.FindNextValueForName (name.AsCString(), entry))
1923 {
1924 DWARFCompileUnitSP cu_sp;
1925 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp);
1926 if (die)
1927 {
1928 if (GetFunction (cu_sp.get(), die, sc))
1929 {
1930 // We found the function, so we should find the line table
1931 // and line table entry as well
1932 LineTable *line_table = sc.comp_unit->GetLineTable();
1933 if (line_table == NULL)
1934 {
1935 if (ParseCompileUnitLineTable(sc))
1936 line_table = sc.comp_unit->GetLineTable();
1937 }
1938 if (line_table != NULL)
1939 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1940
1941 sc_list.Append(sc);
1942 }
1943 }
1944 }
1945
1946 // Return the number of variable that were appended to the list
1947 return sc_list.GetSize() - original_size;
1948}
1949
1950
1951uint32_t
1952SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
1953{
1954 Timer scoped_timer (__PRETTY_FUNCTION__,
1955 "SymbolFileDWARF::FindFunctions (regex = '%s')",
1956 regex.GetText());
1957
1958 std::vector<dw_offset_t> die_offsets;
1959
1960 // If we aren't appending the results to this list, then clear the list
1961 if (!append)
1962 sc_list.Clear();
1963
1964 // Remember how many sc_list are in the list before we search in case
1965 // we are appending the results to a variable list.
1966 uint32_t original_size = sc_list.GetSize();
1967
1968 // Index the DWARF if we haven't already
1969 if (!m_indexed)
1970 Index ();
1971
1972 // Create the pubnames information so we can quickly lookup external symbols by name
1973 // Create the pubnames information so we can quickly lookup external symbols by name
1974 const size_t num_entries = m_name_to_function_die.GetSize();
1975 SymbolContext sc;
1976 for (size_t i=0; i<num_entries; i++)
1977 {
1978 if (!regex.Execute(m_name_to_function_die.GetCStringAtIndex (i)))
1979 continue;
1980
1981 const dw_offset_t die_offset = *m_name_to_function_die.GetValueAtIndex (i);
1982
1983 DWARFCompileUnitSP cu_sp;
1984 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp);
1985 if (die)
1986 {
1987 if (GetFunction (cu_sp.get(), die, sc))
1988 {
1989 // We found the function, so we should find the line table
1990 // and line table entry as well
1991 LineTable *line_table = sc.comp_unit->GetLineTable();
1992 if (line_table == NULL)
1993 {
1994 if (ParseCompileUnitLineTable(sc))
1995 line_table = sc.comp_unit->GetLineTable();
1996 }
1997 if (line_table != NULL)
1998 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1999
2000
2001 sc_list.Append(sc);
2002 }
2003 }
2004 }
2005
2006 // Return the number of variable that were appended to the list
2007 return sc_list.GetSize() - original_size;
2008}
2009
2010#if 0
2011uint32_t
2012SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
2013{
2014 // If we aren't appending the results to this list, then clear the list
2015 if (!append)
2016 types.Clear();
2017
2018 // Create the pubnames information so we can quickly lookup external symbols by name
2019 DWARFDebugPubnames* pubtypes = DebugPubtypes();
2020 if (pubtypes)
2021 {
2022 std::vector<dw_offset_t> die_offsets;
2023 if (!pubtypes->Find(name.AsCString(), false, die_offsets))
2024 {
2025 DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes();
2026 if (pub_base_types && !pub_base_types->Find(name.AsCString(), false, die_offsets))
2027 return 0;
2028 }
2029 return FindTypes(die_offsets, max_matches, encoding, udt_uid, types);
2030 }
2031 return 0;
2032}
2033
2034
2035uint32_t
2036SymbolFileDWARF::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
2037{
2038 // If we aren't appending the results to this list, then clear the list
2039 if (!append)
2040 types.Clear();
2041
2042 // Create the pubnames information so we can quickly lookup external symbols by name
2043 DWARFDebugPubnames* pubtypes = DebugPubtypes();
2044 if (pubtypes)
2045 {
2046 std::vector<dw_offset_t> die_offsets;
2047 if (!pubtypes->Find(regex, die_offsets))
2048 {
2049 DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes();
2050 if (pub_base_types && !pub_base_types->Find(regex, die_offsets))
2051 return 0;
2052 }
2053
2054 return FindTypes(die_offsets, max_matches, encoding, udt_uid, types);
2055 }
2056
2057 return 0;
2058}
2059
2060
2061
2062uint32_t
2063SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
2064{
2065 // Remember how many sc_list are in the list before we search in case
2066 // we are appending the results to a variable list.
2067 uint32_t original_size = types.Size();
2068
2069 const uint32_t num_die_offsets = die_offsets.size();
2070 // Parse all of the types we found from the pubtypes matches
2071 uint32_t i;
2072 uint32_t num_matches = 0;
2073 for (i = 0; i < num_die_offsets; ++i)
2074 {
2075 dw_offset_t die_offset = die_offsets[i];
2076 DWARFCompileUnitSP cu_sp;
2077 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2078
2079 assert(die != NULL);
2080
2081 bool get_type_for_die = true;
2082 if (encoding)
2083 {
2084 // Check if this type has already been uniqued and registers with the module?
2085 Type* type = (Type*)die->GetUserData();
2086 if (type != NULL && type != DIE_IS_BEING_PARSED)
2087 {
2088 get_type_for_die = type->GetEncoding() == encoding;
2089 }
2090 else
2091 {
2092 dw_tag_t tag = die->Tag();
2093 switch (encoding)
2094 {
2095 case Type::address:
2096 case Type::boolean:
2097 case Type::complex_float:
2098 case Type::float_type:
2099 case Type::signed_int:
2100 case Type::signed_char:
2101 case Type::unsigned_int:
2102 case Type::unsigned_char:
2103 case Type::imaginary_float:
2104 case Type::packed_decimal:
2105 case Type::numeric_string:
2106 case Type::edited_string:
2107 case Type::signed_fixed:
2108 case Type::unsigned_fixed:
2109 case Type::decimal_float:
2110 if (tag != DW_TAG_base_type)
2111 get_type_for_die = false;
2112 else
2113 {
2114 if (die->GetAttributeValueAsUnsigned(this, cu_sp.get(), DW_AT_encoding, Type::invalid) != encoding)
2115 get_type_for_die = false;
2116 }
2117 break;
2118
2119 case Type::indirect_const: get_type_for_die = tag == DW_TAG_const_type; break;
2120 case Type::indirect_restrict: get_type_for_die = tag == DW_TAG_restrict_type; break;
2121 case Type::indirect_volatile: get_type_for_die = tag == DW_TAG_volatile_type; break;
2122 case Type::indirect_typedef: get_type_for_die = tag == DW_TAG_typedef; break;
2123 case Type::indirect_pointer: get_type_for_die = tag == DW_TAG_pointer_type; break;
2124 case Type::indirect_reference: get_type_for_die = tag == DW_TAG_reference_type; break;
2125
2126 case Type::user_defined_type:
2127 switch (tag)
2128 {
2129 case DW_TAG_array_type:
2130 get_type_for_die = UserDefTypeArray::OwnsUserDefTypeUID(udt_uid);
2131 break;
2132
2133 case DW_TAG_structure_type:
2134 case DW_TAG_union_type:
2135 case DW_TAG_class_type:
2136 get_type_for_die = UserDefTypeStruct::OwnsUserDefTypeUID(udt_uid);
2137 break;
2138
2139 case DW_TAG_enumeration_type:
2140 get_type_for_die = UserDefTypeEnum::OwnsUserDefTypeUID(udt_uid);
2141 break;
2142
2143 case DW_TAG_subprogram:
2144 case DW_TAG_subroutine_type:
2145 get_type_for_die = UserDefTypeFunction::OwnsUserDefTypeUID(udt_uid);
2146 break;
2147 }
2148 }
2149 }
2150 }
2151
2152 if (get_type_for_die)
2153 {
2154 TypeSP owning_type_sp;
2155 TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, NULL, 0, 0));
2156
2157 if (type_sp.get())
2158 {
2159 // See if we are filtering results based on encoding?
2160 bool add_type = (encoding == Type::invalid);
2161 if (!add_type)
2162 {
2163 // We are filtering base on encoding, so lets check the resulting type encoding
2164 add_type = (encoding == type_sp->GetEncoding());
2165 if (add_type)
2166 {
2167 // The type encoding matches, if this is a user defined type, lets
2168 // make sure the exact user define type uid matches if one was provided
2169 if (encoding == Type::user_defined_type && udt_uid != LLDB_INVALID_UID)
2170 {
2171 UserDefType* udt = type_sp->GetUserDefinedType().get();
2172 if (udt)
2173 add_type = udt->UserDefinedTypeUID() == udt_uid;
2174 }
2175 }
2176 }
2177 // Add the type to our list as long as everything matched
2178 if (add_type)
2179 {
2180 types.InsertUnique(type_sp);
2181 if (++num_matches >= max_matches)
2182 break;
2183 }
2184 }
2185 }
2186 }
2187
2188 // Return the number of variable that were appended to the list
2189 return types.Size() - original_size;
2190}
2191
2192#endif
2193
2194
2195size_t
2196SymbolFileDWARF::ParseChildParameters
2197(
2198 const SymbolContext& sc,
2199 TypeSP& type_sp,
2200 const DWARFCompileUnit* dwarf_cu,
2201 const DWARFDebugInfoEntry *parent_die,
2202 TypeList* type_list,
2203 std::vector<void *>& function_param_types,
2204 std::vector<clang::ParmVarDecl*>& function_param_decls
2205)
2206{
2207 if (parent_die == NULL)
2208 return 0;
2209
2210 size_t count = 0;
2211 const DWARFDebugInfoEntry *die;
2212 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2213 {
2214 dw_tag_t tag = die->Tag();
2215 switch (tag)
2216 {
2217 case DW_TAG_formal_parameter:
2218 {
2219 DWARFDebugInfoEntry::Attributes attributes;
2220 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2221 if (num_attributes > 0)
2222 {
2223 const char *name = NULL;
2224 Declaration decl;
2225 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
2226 // one of None, Auto, Register, Extern, Static, PrivateExtern
2227
2228 clang::VarDecl::StorageClass storage = clang::VarDecl::None;
2229 uint32_t i;
2230 for (i=0; i<num_attributes; ++i)
2231 {
2232 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2233 DWARFFormValue form_value;
2234 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2235 {
2236 switch (attr)
2237 {
2238 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2239 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2240 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2241 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2242 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
2243 case DW_AT_location:
2244 // if (form_value.BlockData())
2245 // {
2246 // const DataExtractor& debug_info_data = debug_info();
2247 // uint32_t block_length = form_value.Unsigned();
2248 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2249 // }
2250 // else
2251 // {
2252 // }
2253 // break;
2254 case DW_AT_artificial:
2255 case DW_AT_const_value:
2256 case DW_AT_default_value:
2257 case DW_AT_description:
2258 case DW_AT_endianity:
2259 case DW_AT_is_optional:
2260 case DW_AT_segment:
2261 case DW_AT_variable_parameter:
2262 default:
2263 case DW_AT_abstract_origin:
2264 case DW_AT_sibling:
2265 break;
2266 }
2267 }
2268 }
2269 Type *dc_type = ResolveTypeUID(param_type_die_offset);
2270 if (dc_type)
2271 {
2272 function_param_types.push_back (dc_type->GetOpaqueClangQualType());
2273
2274 clang::ParmVarDecl *param_var_decl = type_list->GetClangASTContext().CreateParmeterDeclaration (name, dc_type->GetOpaqueClangQualType(), storage);
2275 assert(param_var_decl);
2276 function_param_decls.push_back(param_var_decl);
2277 }
2278 }
2279 }
2280 break;
2281
2282 default:
2283 break;
2284 }
2285 }
2286 return count;
2287}
2288
2289size_t
2290SymbolFileDWARF::ParseChildEnumerators
2291(
2292 const SymbolContext& sc,
2293 TypeSP& type_sp,
2294 void * enumerator_qual_type,
2295 uint32_t enumerator_byte_size,
2296 const DWARFCompileUnit* dwarf_cu,
2297 const DWARFDebugInfoEntry *parent_die
2298)
2299{
2300 if (parent_die == NULL)
2301 return 0;
2302
2303 size_t enumerators_added = 0;
2304 const DWARFDebugInfoEntry *die;
2305 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2306 {
2307 const dw_tag_t tag = die->Tag();
2308 if (tag == DW_TAG_enumerator)
2309 {
2310 DWARFDebugInfoEntry::Attributes attributes;
2311 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2312 if (num_child_attributes > 0)
2313 {
2314 const char *name = NULL;
2315 bool got_value = false;
2316 int64_t enum_value = 0;
2317 Declaration decl;
2318
2319 uint32_t i;
2320 for (i=0; i<num_child_attributes; ++i)
2321 {
2322 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2323 DWARFFormValue form_value;
2324 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2325 {
2326 switch (attr)
2327 {
2328 case DW_AT_const_value:
2329 got_value = true;
2330 enum_value = form_value.Unsigned();
2331 break;
2332
2333 case DW_AT_name:
2334 name = form_value.AsCString(&get_debug_str_data());
2335 break;
2336
2337 case DW_AT_description:
2338 default:
2339 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2340 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2341 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2342 case DW_AT_sibling:
2343 break;
2344 }
2345 }
2346 }
2347
2348 if (name && name[0] && got_value)
2349 {
2350 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2351 type_list->GetClangASTContext().AddEnumerationValueToEnumerationType (type_sp->GetOpaqueClangQualType(), enumerator_qual_type, decl, name, enum_value, enumerator_byte_size * 8);
2352 ++enumerators_added;
2353 }
2354 }
2355 }
2356 }
2357 return enumerators_added;
2358}
2359
2360void
2361SymbolFileDWARF::ParseChildArrayInfo
2362(
2363 const SymbolContext& sc,
2364 const DWARFCompileUnit* dwarf_cu,
2365 const DWARFDebugInfoEntry *parent_die,
2366 int64_t& first_index,
2367 std::vector<uint64_t>& element_orders,
2368 uint32_t& byte_stride,
2369 uint32_t& bit_stride
2370)
2371{
2372 if (parent_die == NULL)
2373 return;
2374
2375 const DWARFDebugInfoEntry *die;
2376 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2377 {
2378 const dw_tag_t tag = die->Tag();
2379 switch (tag)
2380 {
2381 case DW_TAG_enumerator:
2382 {
2383 DWARFDebugInfoEntry::Attributes attributes;
2384 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2385 if (num_child_attributes > 0)
2386 {
2387 const char *name = NULL;
2388 bool got_value = false;
2389 int64_t enum_value = 0;
2390
2391 uint32_t i;
2392 for (i=0; i<num_child_attributes; ++i)
2393 {
2394 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2395 DWARFFormValue form_value;
2396 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2397 {
2398 switch (attr)
2399 {
2400 case DW_AT_const_value:
2401 got_value = true;
2402 enum_value = form_value.Unsigned();
2403 break;
2404
2405 case DW_AT_name:
2406 name = form_value.AsCString(&get_debug_str_data());
2407 break;
2408
2409 case DW_AT_description:
2410 default:
2411 case DW_AT_decl_file:
2412 case DW_AT_decl_line:
2413 case DW_AT_decl_column:
2414 case DW_AT_sibling:
2415 break;
2416 }
2417 }
2418 }
2419 }
2420 }
2421 break;
2422
2423 case DW_TAG_subrange_type:
2424 {
2425 DWARFDebugInfoEntry::Attributes attributes;
2426 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2427 if (num_child_attributes > 0)
2428 {
2429 const char *name = NULL;
2430 bool got_value = false;
2431 uint64_t byte_size = 0;
2432 int64_t enum_value = 0;
2433 uint64_t num_elements = 0;
2434 uint64_t lower_bound = 0;
2435 uint64_t upper_bound = 0;
2436 uint32_t i;
2437 for (i=0; i<num_child_attributes; ++i)
2438 {
2439 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2440 DWARFFormValue form_value;
2441 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2442 {
2443 switch (attr)
2444 {
2445 case DW_AT_const_value:
2446 got_value = true;
2447 enum_value = form_value.Unsigned();
2448 break;
2449
2450 case DW_AT_name:
2451 name = form_value.AsCString(&get_debug_str_data());
2452 break;
2453
2454 case DW_AT_count:
2455 num_elements = form_value.Unsigned();
2456 break;
2457
2458 case DW_AT_bit_stride:
2459 bit_stride = form_value.Unsigned();
2460 break;
2461
2462 case DW_AT_byte_stride:
2463 byte_stride = form_value.Unsigned();
2464 break;
2465
2466 case DW_AT_byte_size:
2467 byte_size = form_value.Unsigned();
2468 break;
2469
2470 case DW_AT_lower_bound:
2471 lower_bound = form_value.Unsigned();
2472 break;
2473
2474 case DW_AT_upper_bound:
2475 upper_bound = form_value.Unsigned();
2476 break;
2477
2478 default:
2479 //printf("0x%8.8x: %-30s skipping attribute at 0x%8.8x: %s\n", die->GetOffset(), DW_TAG_value_to_name(tag), attributes.die_offsets[i], DW_AT_value_to_name(attr)); // remove this, debug only
2480
2481 case DW_AT_abstract_origin:
2482 case DW_AT_accessibility:
2483 case DW_AT_allocated:
2484 case DW_AT_associated:
2485 case DW_AT_data_location:
2486 case DW_AT_declaration:
2487 case DW_AT_description:
2488 case DW_AT_sibling:
2489 case DW_AT_threads_scaled:
2490 case DW_AT_type:
2491 case DW_AT_visibility:
2492 break;
2493 }
2494 }
2495 }
2496
2497 if (upper_bound > lower_bound)
2498 num_elements = upper_bound - lower_bound + 1;
2499
2500 if (num_elements > 0)
2501 element_orders.push_back (num_elements);
2502 }
2503 }
2504 break;
2505 }
2506 }
2507}
2508
2509Type*
2510SymbolFileDWARF::GetUniquedTypeForDIEOffset(dw_offset_t type_die_offset, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx, bool safe)
2511{
2512 if (type_die_offset != DW_INVALID_OFFSET)
2513 {
2514 DWARFCompileUnitSP cu_sp;
2515 const DWARFDebugInfoEntry* type_die = DebugInfo()->GetDIEPtr(type_die_offset, &cu_sp);
2516 assert(type_die != NULL);
2517 GetTypeForDIE(cu_sp.get(), type_die, owning_type_sp, child_type, idx);
2518 // Return the uniqued type if there is one
2519 Type* type = (Type*)type_die->GetUserData();
2520 if (type == DIE_IS_BEING_PARSED && safe)
2521 return NULL;
2522 return type;
2523 }
2524 return NULL;
2525}
2526
2527TypeSP
2528SymbolFileDWARF::GetTypeForDIE(DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx)
2529{
2530 TypeSP type_sp;
2531 if (die != NULL)
2532 {
2533 assert(cu != NULL);
2534 Type *type_ptr = (Type *)die->GetUserData();
2535 if (type_ptr == NULL)
2536 {
2537 SymbolContext sc(GetCompUnitForDWARFCompUnit(cu));
2538 bool type_is_new = false;
2539 type_sp = ParseType(sc, cu, die, type_is_new);
2540 type_ptr = (Type *)die->GetUserData();
2541 if (owning_type_sp.get() == NULL)
2542 owning_type_sp = type_sp;
2543 }
2544 else if (type_ptr != DIE_IS_BEING_PARSED)
2545 {
2546 // Grab the existing type from the master types lists
2547 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(type_ptr->GetID());
2548 }
2549
2550 }
2551 return type_sp;
2552}
2553
2554clang::DeclContext *
2555SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2556{
2557 if (die_offset != DW_INVALID_OFFSET)
2558 {
2559 DWARFCompileUnitSP cu_sp;
2560 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2561 return GetClangDeclContextForDIE (cu_sp.get(), die);
2562 }
2563 return NULL;
2564}
2565
2566
2567
2568clang::DeclContext *
2569SymbolFileDWARF::GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
2570{
2571 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2572 if (pos != m_die_to_decl_ctx.end())
2573 return pos->second;
2574
2575 while (die != NULL)
2576 {
2577 switch (die->Tag())
2578 {
2579 case DW_TAG_namespace:
2580 {
2581 const char *namespace_name = die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL);
2582 if (namespace_name)
2583 {
2584 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2585 assert(type_list);
2586 Declaration decl; // TODO: fill in the decl object
2587 clang::NamespaceDecl *namespace_decl = type_list->GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (cu, die->GetParent()));
2588 if (namespace_decl)
2589 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2590 return namespace_decl;
2591 }
2592 }
2593 break;
2594
2595 default:
2596 break;
2597 }
2598 clang::DeclContext *decl_ctx;
2599 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_specification, DW_INVALID_OFFSET));
2600 if (decl_ctx)
2601 return decl_ctx;
2602
2603 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET));
2604 if (decl_ctx)
2605 return decl_ctx;
2606
2607 die = die->GetParent();
2608 }
2609 return NULL;
2610}
2611
2612TypeSP
2613SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new)
2614{
2615 TypeSP type_sp;
2616
2617 uint32_t accessibility = clang::AS_none;
2618 if (die != NULL)
2619 {
2620 dw_tag_t tag = die->Tag();
2621 if (die->GetUserData() == NULL)
2622 {
2623 type_is_new = true;
2624
2625 bool is_forward_declaration = false;
2626 DWARFDebugInfoEntry::Attributes attributes;
2627 const char *type_name_cstr = NULL;
2628 ConstString type_name_dbstr;
2629 Type::EncodingUIDType encoding_uid_type = Type::eIsTypeWithUID;
2630 void *clang_type = NULL;
2631
2632 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2633 dw_attr_t attr;
2634
2635 switch (tag)
2636 {
2637 case DW_TAG_base_type:
2638 case DW_TAG_pointer_type:
2639 case DW_TAG_reference_type:
2640 case DW_TAG_typedef:
2641 case DW_TAG_const_type:
2642 case DW_TAG_restrict_type:
2643 case DW_TAG_volatile_type:
2644 {
2645 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2646 // Set a bit that lets us know that we are currently parsing this
2647 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2648
2649 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2650 Declaration decl;
2651 uint32_t encoding = 0;
2652 size_t byte_size = 0;
2653 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
2654
2655 if (num_attributes > 0)
2656 {
2657 uint32_t i;
2658 for (i=0; i<num_attributes; ++i)
2659 {
2660 attr = attributes.AttributeAtIndex(i);
2661 DWARFFormValue form_value;
2662 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2663 {
2664 switch (attr)
2665 {
2666 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2667 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2668 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2669 case DW_AT_name:
2670 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2671 type_name_dbstr.SetCString(type_name_cstr);
2672 break;
2673 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
2674 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
2675 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2676 default:
2677 case DW_AT_sibling:
2678 break;
2679 }
2680 }
2681 }
2682 }
2683
2684 switch (tag)
2685 {
2686 default:
2687 case DW_TAG_base_type:
2688 clang_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, encoding, byte_size * 8);
2689 break;
2690
2691 case DW_TAG_pointer_type:
2692 // The encoding_uid will be embedded into the
2693 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2694 encoding_uid_type = Type::ePointerToTypeWithUID;
2695 break;
2696
2697 case DW_TAG_reference_type:
2698 // The encoding_uid will be embedded into the
2699 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2700 encoding_uid_type = Type::eLValueReferenceToTypeWithUID;
2701 break;
2702
2703 case DW_TAG_typedef:
2704 // The encoding_uid will be embedded into the
2705 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2706 encoding_uid_type = Type::eTypedefToTypeWithUID;
2707 break;
2708
2709 case DW_TAG_const_type:
2710 // The encoding_uid will be embedded into the
2711 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2712 encoding_uid_type = Type::eIsConstTypeWithUID; //ClangASTContext::AddConstModifier (clang_type);
2713 break;
2714
2715 case DW_TAG_restrict_type:
2716 // The encoding_uid will be embedded into the
2717 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2718 encoding_uid_type = Type::eIsRestrictTypeWithUID; //ClangASTContext::AddRestrictModifier (clang_type);
2719 break;
2720
2721 case DW_TAG_volatile_type:
2722 // The encoding_uid will be embedded into the
2723 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2724 encoding_uid_type = Type::eIsVolatileTypeWithUID; //ClangASTContext::AddVolatileModifier (clang_type);
2725 break;
2726 }
2727
2728 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, encoding_uid_type, &decl, clang_type));
2729
2730 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2731
2732
2733// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
2734// if (encoding_type != NULL)
2735// {
2736// if (encoding_type != DIE_IS_BEING_PARSED)
2737// type_sp->SetEncodingType(encoding_type);
2738// else
2739// m_indirect_fixups.push_back(type_sp.get());
2740// }
2741 }
2742 break;
2743
2744 case DW_TAG_structure_type:
2745 case DW_TAG_union_type:
2746 case DW_TAG_class_type:
2747 {
2748 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2749 // Set a bit that lets us know that we are currently parsing this
2750 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2751
2752 size_t byte_size = 0;
2753 //bool struct_is_class = false;
2754 Declaration decl;
2755 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2756 if (num_attributes > 0)
2757 {
2758 uint32_t i;
2759 for (i=0; i<num_attributes; ++i)
2760 {
2761 attr = attributes.AttributeAtIndex(i);
2762 DWARFFormValue form_value;
2763 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2764 {
2765 switch (attr)
2766 {
2767 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2768 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2769 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2770 case DW_AT_name:
2771 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2772 type_name_dbstr.SetCString(type_name_cstr);
2773 break;
2774 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
2775 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break; break;
2776 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
2777 case DW_AT_allocated:
2778 case DW_AT_associated:
2779 case DW_AT_data_location:
2780 case DW_AT_description:
2781 case DW_AT_start_scope:
2782 case DW_AT_visibility:
2783 default:
2784 case DW_AT_sibling:
2785 break;
2786 }
2787 }
2788 }
2789 }
2790
2791 int tag_decl_kind = -1;
2792 int default_accessibility = clang::AS_none;
2793 if (tag == DW_TAG_structure_type)
2794 {
2795 tag_decl_kind = clang::TTK_Struct;
2796 default_accessibility = clang::AS_public;
2797 }
2798 else if (tag == DW_TAG_union_type)
2799 {
2800 tag_decl_kind = clang::TTK_Union;
2801 default_accessibility = clang::AS_public;
2802 }
2803 else if (tag == DW_TAG_class_type)
2804 {
2805 tag_decl_kind = clang::TTK_Class;
2806 default_accessibility = clang::AS_private;
2807 }
2808
2809 assert (tag_decl_kind != -1);
2810 clang_type = type_list->GetClangASTContext().CreateRecordType (type_name_cstr, tag_decl_kind, GetClangDeclContextForDIE (dwarf_cu, die));
2811
2812 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
2813 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
2814
2815 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2816
2817// assert(type_sp.get());
2818// if (accessibility)
2819// type_sp->SetAccess(accessibility);
2820//
2821 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
2822 if (die->HasChildren())
2823 {
2824 std::vector<clang::CXXBaseSpecifier *> base_classes;
2825 std::vector<int> member_accessibilities;
2826 bool is_a_class = false;
2827 ParseChildMembers(sc, type_sp, dwarf_cu, die, base_classes, member_accessibilities, default_accessibility, is_a_class);
2828 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
2829 // need to tell the clang type it is actually a class.
2830 if (is_a_class && tag_decl_kind != clang::TTK_Class)
2831 type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class);
2832
2833 // Since DW_TAG_structure_type gets used for both classes
2834 // and structures, we may need to set any DW_TAG_member
2835 // fields to have a "private" access if none was specified.
2836 // When we parsed the child members we tracked that actual
2837 // accessibility value for each DW_TAG_member in the
2838 // "member_accessibilities" array. If the value for the
2839 // member is zero, then it was set to the "default_accessibility"
2840 // which for structs was "public". Below we correct this
2841 // by setting any fields to "private" that weren't correctly
2842 // set.
2843 if (is_a_class && !member_accessibilities.empty())
2844 {
2845 // This is a class and all members that didn't have
2846 // their access specified are private.
2847 type_list->GetClangASTContext().SetDefaultAccessForRecordFields (clang_type, clang::AS_private, member_accessibilities.data(), member_accessibilities.size());
2848 }
2849
2850 if (!base_classes.empty())
2851 {
2852 type_list->GetClangASTContext().SetBaseClassesForClassType (clang_type, base_classes.data(), base_classes.size());
2853 }
2854 }
2855 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
2856 }
2857 break;
2858
2859 case DW_TAG_enumeration_type:
2860 {
2861 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2862 // Set a bit that lets us know that we are currently parsing this
2863 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2864
2865 size_t byte_size = 0;
2866 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
2867 Declaration decl;
2868
2869 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2870 if (num_attributes > 0)
2871 {
2872 uint32_t i;
2873
2874 for (i=0; i<num_attributes; ++i)
2875 {
2876 attr = attributes.AttributeAtIndex(i);
2877 DWARFFormValue form_value;
2878 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2879 {
2880 switch (attr)
2881 {
2882 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2883 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2884 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2885 case DW_AT_name:
2886 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2887 type_name_dbstr.SetCString(type_name_cstr);
2888 break;
2889 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2890 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
2891 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
2892 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
2893 case DW_AT_allocated:
2894 case DW_AT_associated:
2895 case DW_AT_bit_stride:
2896 case DW_AT_byte_stride:
2897 case DW_AT_data_location:
2898 case DW_AT_description:
2899 case DW_AT_start_scope:
2900 case DW_AT_visibility:
2901 case DW_AT_specification:
2902 case DW_AT_abstract_origin:
2903 case DW_AT_sibling:
2904 break;
2905 }
2906 }
2907 }
2908
2909 clang_type = type_list->GetClangASTContext().CreateEnumerationType(decl, type_name_cstr);
2910 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
2911 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, Type::eIsTypeWithUID, &decl, clang_type));
2912
2913 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2914
2915 if (die->HasChildren())
2916 {
2917 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
2918 void *enumerator_qual_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, DW_ATE_signed, byte_size * 8);
2919 ParseChildEnumerators(sc, type_sp, enumerator_qual_type, byte_size, dwarf_cu, die);
2920 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
2921 }
2922 }
2923 }
2924 break;
2925
2926 case DW_TAG_subprogram:
2927 case DW_TAG_subroutine_type:
2928 {
2929 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2930 // Set a bit that lets us know that we are currently parsing this
2931 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2932
2933 const char *mangled = NULL;
2934 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
2935 Declaration decl;
2936 bool isVariadic = false;
2937 bool is_inline = false;
2938 unsigned type_quals = 0;
2939 clang::FunctionDecl::StorageClass storage = clang::FunctionDecl::None;//, Extern, Static, PrivateExtern
2940
2941
2942 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2943 if (num_attributes > 0)
2944 {
2945 uint32_t i;
2946 for (i=0; i<num_attributes; ++i)
2947 {
2948 attr = attributes.AttributeAtIndex(i);
2949 DWARFFormValue form_value;
2950 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2951 {
2952 switch (attr)
2953 {
2954 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2955 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2956 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2957 case DW_AT_name:
2958 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2959 type_name_dbstr.SetCString(type_name_cstr);
2960 break;
2961
2962 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
2963 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
2964 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
2965 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
2966 case DW_AT_external:
2967 if (form_value.Unsigned())
2968 {
2969 if (storage == clang::FunctionDecl::None)
2970 storage = clang::FunctionDecl::Extern;
2971 else
2972 storage = clang::FunctionDecl::PrivateExtern;
2973 }
2974 break;
2975 case DW_AT_inline:
2976 is_inline = form_value.Unsigned() != 0;
2977 break;
2978
2979 case DW_AT_allocated:
2980 case DW_AT_associated:
2981 case DW_AT_address_class:
2982 case DW_AT_artificial:
2983 case DW_AT_calling_convention:
2984 case DW_AT_data_location:
2985 case DW_AT_elemental:
2986 case DW_AT_entry_pc:
2987 case DW_AT_explicit:
2988 case DW_AT_frame_base:
2989 case DW_AT_high_pc:
2990 case DW_AT_low_pc:
2991 case DW_AT_object_pointer:
2992 case DW_AT_prototyped:
2993 case DW_AT_pure:
2994 case DW_AT_ranges:
2995 case DW_AT_recursive:
2996 case DW_AT_return_addr:
2997 case DW_AT_segment:
2998 case DW_AT_specification:
2999 case DW_AT_start_scope:
3000 case DW_AT_static_link:
3001 case DW_AT_trampoline:
3002 case DW_AT_visibility:
3003 case DW_AT_virtuality:
3004 case DW_AT_vtable_elem_location:
3005 case DW_AT_abstract_origin:
3006 case DW_AT_description:
3007 case DW_AT_sibling:
3008 break;
3009 }
3010 }
3011 }
3012
3013 void *return_clang_type = NULL;
3014 Type *func_type = ResolveTypeUID(type_die_offset);
3015 if (func_type)
3016 return_clang_type = func_type->GetOpaqueClangQualType();
3017 else
3018 return_clang_type = type_list->GetClangASTContext().GetVoidBuiltInType();
3019
3020 std::vector<void *> function_param_types;
3021 std::vector<clang::ParmVarDecl*> function_param_decls;
3022
3023 // Parse the function children for the parameters
3024 ParseChildParameters(sc, type_sp, dwarf_cu, die, type_list, function_param_types, function_param_decls);
3025
3026 clang_type = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), isVariadic, type_quals);
3027 if (type_name_cstr)
3028 {
3029 clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline);
3030 // Add the decl to our DIE to decl context map
3031 assert (function_decl);
3032 m_die_to_decl_ctx[die] = function_decl;
3033 if (!function_param_decls.empty())
3034 type_list->GetClangASTContext().SetFunctionParameters (function_decl, function_param_decls.data(), function_param_decls.size());
3035 }
3036 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, 0, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
3037
3038 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
3039 assert(type_sp.get());
3040 }
3041 }
3042 break;
3043
3044 case DW_TAG_array_type:
3045 {
3046 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
3047 // Set a bit that lets us know that we are currently parsing this
3048 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
3049
3050 size_t byte_size = 0;
3051 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
3052 Declaration decl;
3053 int64_t first_index = 0;
3054 uint32_t byte_stride = 0;
3055 uint32_t bit_stride = 0;
3056 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
3057
3058 if (num_attributes > 0)
3059 {
3060 uint32_t i;
3061 for (i=0; i<num_attributes; ++i)
3062 {
3063 attr = attributes.AttributeAtIndex(i);
3064 DWARFFormValue form_value;
3065 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3066 {
3067 switch (attr)
3068 {
3069 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3070 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3071 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3072 case DW_AT_name:
3073 type_name_cstr = form_value.AsCString(&get_debug_str_data());
3074 type_name_dbstr.SetCString(type_name_cstr);
3075 break;
3076
3077 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
3078 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3079 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3080 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
3081 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
3082 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
3083 case DW_AT_allocated:
3084 case DW_AT_associated:
3085 case DW_AT_data_location:
3086 case DW_AT_description:
3087 case DW_AT_ordering:
3088 case DW_AT_start_scope:
3089 case DW_AT_visibility:
3090 case DW_AT_specification:
3091 case DW_AT_abstract_origin:
3092 case DW_AT_sibling:
3093 break;
3094 }
3095 }
3096 }
3097
3098 Type *element_type = ResolveTypeUID(type_die_offset);
3099
3100 if (element_type)
3101 {
3102 std::vector<uint64_t> element_orders;
3103 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
3104 if (byte_stride == 0 && bit_stride == 0)
3105 byte_stride = element_type->GetByteSize();
3106 void *array_element_type = element_type->GetOpaqueClangQualType();
3107 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3108 uint64_t num_elements = 0;
3109 std::vector<uint64_t>::const_reverse_iterator pos;
3110 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3111 for (pos = element_orders.rbegin(); pos != end; ++pos)
3112 {
3113 num_elements = *pos;
3114 clang_type = type_list->GetClangASTContext().CreateArrayType (array_element_type, num_elements, num_elements * array_element_bit_stride);
3115 array_element_type = clang_type;
3116 array_element_bit_stride = array_element_bit_stride * num_elements;
3117 }
3118 ConstString empty_name;
3119 type_sp.reset( new Type(die->GetOffset(), this, empty_name, array_element_bit_stride / 8, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
3120 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
3121 }
3122 }
3123 }
3124 break;
3125
Greg Claytonfa970692010-06-12 01:20:30 +00003126 case DW_TAG_ptr_to_member_type:
3127 {
3128 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3129 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3130
3131 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
3132
3133 if (num_attributes > 0) {
3134 uint32_t i;
3135 for (i=0; i<num_attributes; ++i)
3136 {
3137 attr = attributes.AttributeAtIndex(i);
3138 DWARFFormValue form_value;
3139 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3140 {
3141 switch (attr)
3142 {
3143 case DW_AT_type:
3144 type_die_offset = form_value.Reference(dwarf_cu); break;
3145 case DW_AT_containing_type:
3146 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3147 }
3148 }
3149 }
3150
3151 Type *pointee_type = ResolveTypeUID(type_die_offset);
3152 Type *class_type = ResolveTypeUID(containing_type_die_offset);
3153
3154 void *pointee_clang_type = pointee_type->GetOpaqueClangQualType();
Greg Claytonf6e509a2010-06-12 15:33:14 +00003155 void *class_clang_type = class_type->GetOpaqueClangQualType();
Greg Claytonfa970692010-06-12 01:20:30 +00003156
3157 void *clang_type = type_list->GetClangASTContext().CreateMemberPointerType(pointee_clang_type, class_clang_type);
3158
3159 size_t byte_size = ClangASTContext::GetTypeBitSize(type_list->GetClangASTContext().getASTContext(), clang_type) / 8;
3160
3161 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, NULL, clang_type));
3162 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
3163 }
3164
3165 break;
3166 }
Chris Lattner24943d22010-06-08 16:52:24 +00003167 default:
Greg Claytonfa970692010-06-12 01:20:30 +00003168 assert(false && "Unhandled type tag!");
Chris Lattner24943d22010-06-08 16:52:24 +00003169 break;
3170 }
3171
3172 if (type_sp.get())
3173 {
3174 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3175 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3176
3177 SymbolContextScope * symbol_context_scope = NULL;
3178 if (sc_parent_tag == DW_TAG_compile_unit)
3179 {
3180 symbol_context_scope = sc.comp_unit;
3181 }
3182 else if (sc.function != NULL)
3183 {
3184 symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset());
3185 if (symbol_context_scope == NULL)
3186 symbol_context_scope = sc.function;
3187 }
3188
3189 if (symbol_context_scope != NULL)
3190 {
3191 type_sp->SetSymbolContextScope(symbol_context_scope);
3192 }
3193
3194// if (udt_sp.get())
3195// {
3196// if (is_forward_declaration)
3197// udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
3198// type_sp->SetUserDefinedType(udt_sp);
3199// }
3200
3201 if (type_sp.unique())
3202 {
3203 // We are ready to put this type into the uniqued list up at the module level
3204 TypeSP uniqued_type_sp(m_obj_file->GetModule()->GetTypeList()->InsertUnique(type_sp));
3205
3206 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(uniqued_type_sp.get());
3207
3208 type_sp = uniqued_type_sp;
3209 }
3210 }
3211 }
3212 else
3213 {
3214 switch (tag)
3215 {
3216 case DW_TAG_base_type:
3217 case DW_TAG_pointer_type:
3218 case DW_TAG_reference_type:
3219 case DW_TAG_typedef:
3220 case DW_TAG_const_type:
3221 case DW_TAG_restrict_type:
3222 case DW_TAG_volatile_type:
3223 case DW_TAG_structure_type:
3224 case DW_TAG_union_type:
3225 case DW_TAG_class_type:
3226 case DW_TAG_enumeration_type:
3227 case DW_TAG_subprogram:
3228 case DW_TAG_subroutine_type:
3229 case DW_TAG_array_type:
3230 {
3231 Type *existing_type = (Type*)die->GetUserData();
3232 if (existing_type != DIE_IS_BEING_PARSED)
3233 {
3234 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(existing_type->GetID());
3235 }
3236 }
3237 break;
3238 default:
3239 //assert(!"invalid type tag...");
3240 break;
3241 }
3242 }
3243 }
3244 return type_sp;
3245}
3246
3247size_t
3248SymbolFileDWARF::ParseTypes (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children)
3249{
3250 size_t types_added = 0;
3251 while (die != NULL)
3252 {
3253 bool type_is_new = false;
3254 if (ParseType(sc, dwarf_cu, die, type_is_new).get())
3255 {
3256 if (type_is_new)
3257 ++types_added;
3258 }
3259
3260 if (parse_children && die->HasChildren())
3261 {
3262 if (die->Tag() == DW_TAG_subprogram)
3263 {
3264 SymbolContext child_sc(sc);
3265 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3266 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3267 }
3268 else
3269 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3270 }
3271
3272 if (parse_siblings)
3273 die = die->GetSibling();
3274 else
3275 die = NULL;
3276 }
3277 return types_added;
3278}
3279
3280
3281size_t
3282SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3283{
3284 assert(sc.comp_unit && sc.function);
3285 size_t functions_added = 0;
3286 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3287 if (dwarf_cu)
3288 {
3289 dw_offset_t function_die_offset = sc.function->GetID();
3290 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3291 if (function_die)
3292 {
3293 ParseFunctionBlocks(sc, Block::RootID, dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
3294 }
3295 }
3296
3297 return functions_added;
3298}
3299
3300
3301size_t
3302SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3303{
3304 // At least a compile unit must be valid
3305 assert(sc.comp_unit);
3306 size_t types_added = 0;
3307 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3308 if (dwarf_cu)
3309 {
3310 if (sc.function)
3311 {
3312 dw_offset_t function_die_offset = sc.function->GetID();
3313 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3314 if (func_die && func_die->HasChildren())
3315 {
3316 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3317 }
3318 }
3319 else
3320 {
3321 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3322 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3323 {
3324 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3325 }
3326 }
3327 }
3328
3329 return types_added;
3330}
3331
3332size_t
3333SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3334{
3335 if (sc.comp_unit != NULL)
3336 {
3337 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3338
3339 if (dwarf_cu == NULL)
3340 return 0;
3341
3342 if (sc.function)
3343 {
3344 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
3345 return ParseVariables(sc, dwarf_cu, function_die->GetFirstChild(), true, true);
3346 }
3347 else if (sc.comp_unit)
3348 {
3349 uint32_t vars_added = 0;
3350 VariableListSP variables (sc.comp_unit->GetVariableList(false));
3351
3352 if (variables.get() == NULL)
3353 {
3354 variables.reset(new VariableList());
3355 sc.comp_unit->SetVariableList(variables);
3356
3357 // Index if we already haven't to make sure the compile units
3358 // get indexed and make their global DIE index list
3359 if (!m_indexed)
3360 Index ();
3361
3362 const size_t num_globals = dwarf_cu->GetNumGlobals();
3363 for (size_t idx=0; idx<num_globals; ++idx)
3364 {
3365 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetGlobalDIEAtIndex (idx)));
3366 if (var_sp)
3367 {
3368 variables->AddVariable(var_sp);
3369 ++vars_added;
3370 }
3371 }
3372 }
3373 return vars_added;
3374 }
3375 }
3376 return 0;
3377}
3378
3379
3380VariableSP
3381SymbolFileDWARF::ParseVariableDIE
3382(
3383 const SymbolContext& sc,
3384 const DWARFCompileUnit* dwarf_cu,
3385 const DWARFDebugInfoEntry *die
3386)
3387{
3388
3389 VariableSP var_sp;
3390
3391 const dw_tag_t tag = die->Tag();
3392 DWARFDebugInfoEntry::Attributes attributes;
3393 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
3394 if (num_attributes > 0)
3395 {
3396 const char *name = NULL;
3397 Declaration decl;
3398 uint32_t i;
3399 TypeSP type_sp;
3400 Type *var_type = NULL;
3401 DWARFExpression location;
3402 bool is_external = false;
3403 bool is_artificial = false;
3404 uint32_t accessibility = clang::AS_none;
3405
3406 for (i=0; i<num_attributes; ++i)
3407 {
3408 dw_attr_t attr = attributes.AttributeAtIndex(i);
3409 DWARFFormValue form_value;
3410 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3411 {
3412 switch (attr)
3413 {
3414 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3415 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3416 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3417 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
3418 case DW_AT_type: var_type = GetUniquedTypeForDIEOffset(form_value.Reference(dwarf_cu), type_sp, 0, 0, false); break;
3419 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
3420 case DW_AT_location:
3421 {
3422 if (form_value.BlockData())
3423 {
3424 const DataExtractor& debug_info_data = get_debug_info_data();
3425
3426 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3427 uint32_t block_length = form_value.Unsigned();
3428 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length, NULL);
3429 }
3430 else
3431 {
3432 const DataExtractor& debug_loc_data = get_debug_loc_data();
3433 const dw_offset_t debug_loc_offset = form_value.Unsigned();
3434
3435 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
3436 if (loc_list_length > 0)
3437 {
3438 Address base_address(dwarf_cu->GetBaseAddress(), m_obj_file->GetSectionList());
3439 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length, &base_address);
3440 }
3441 }
3442 }
3443 break;
3444
3445 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
3446 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
3447 case DW_AT_const_value:
3448 case DW_AT_declaration:
3449 case DW_AT_description:
3450 case DW_AT_endianity:
3451 case DW_AT_segment:
3452 case DW_AT_start_scope:
3453 case DW_AT_visibility:
3454 default:
3455 case DW_AT_abstract_origin:
3456 case DW_AT_sibling:
3457 case DW_AT_specification:
3458 break;
3459 }
3460 }
3461 }
3462
3463 if (location.IsValid())
3464 {
3465 assert(var_type != DIE_IS_BEING_PARSED);
3466
3467 ConstString var_name(name);
3468
3469 ValueType scope = eValueTypeInvalid;
3470
3471 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3472 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3473
3474 if (tag == DW_TAG_formal_parameter)
3475 scope = eValueTypeVariableArgument;
3476 else if (is_external || parent_tag == DW_TAG_compile_unit)
3477 scope = eValueTypeVariableGlobal;
3478 else
3479 scope = eValueTypeVariableLocal;
3480
3481 SymbolContextScope * symbol_context_scope = NULL;
3482 if (parent_tag == DW_TAG_compile_unit)
3483 {
3484 symbol_context_scope = sc.comp_unit;
3485 }
3486 else if (sc.function != NULL)
3487 {
3488 symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset());
3489 if (symbol_context_scope == NULL)
3490 symbol_context_scope = sc.function;
3491 }
3492
3493 assert(symbol_context_scope != NULL);
3494 var_sp.reset (new Variable(die->GetOffset(),
3495 var_name,
3496 var_type,
3497 scope,
3498 symbol_context_scope,
3499 &decl,
3500 location,
3501 is_external,
3502 is_artificial));
3503 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(var_sp.get());
3504 }
3505 }
3506 return var_sp;
3507}
3508
3509size_t
3510SymbolFileDWARF::ParseVariables
3511(
3512 const SymbolContext& sc,
3513 const DWARFCompileUnit* dwarf_cu,
3514 const DWARFDebugInfoEntry *orig_die,
3515 bool parse_siblings,
3516 bool parse_children,
3517 VariableList* cc_variable_list
3518)
3519{
3520 if (orig_die == NULL)
3521 return 0;
3522
3523 size_t vars_added = 0;
3524 const DWARFDebugInfoEntry *die = orig_die;
3525 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
3526 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3527 VariableListSP variables;
3528 switch (parent_tag)
3529 {
3530 case DW_TAG_compile_unit:
3531 if (sc.comp_unit != NULL)
3532 {
3533 variables = sc.comp_unit->GetVariableList(false);
3534 if (variables.get() == NULL)
3535 {
3536 variables.reset(new VariableList());
3537 sc.comp_unit->SetVariableList(variables);
3538 }
3539 }
3540 else
3541 {
3542 assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
3543 vars_added = 0;
3544 }
3545 break;
3546
3547 case DW_TAG_subprogram:
3548 case DW_TAG_inlined_subroutine:
3549 case DW_TAG_lexical_block:
3550 if (sc.function != NULL)
3551 {
3552 // Check to see if we already have parsed the variables for the given scope
3553 variables = sc.function->GetBlocks(true).GetVariableList(sc_parent_die->GetOffset(), false, false);
3554 if (variables.get() == NULL)
3555 {
3556 variables.reset(new VariableList());
3557 sc.function->GetBlocks(true).SetVariableList(sc_parent_die->GetOffset(), variables);
3558 }
3559 }
3560 else
3561 {
3562 assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
3563 vars_added = 0;
3564 }
3565 break;
3566
3567 default:
3568 assert(!"Didn't find appropriate parent DIE for variable list...");
3569 break;
3570 }
3571
3572 // We need to have a variable list at this point that we can add variables to
3573 assert(variables.get());
3574
3575 while (die != NULL)
3576 {
3577 dw_tag_t tag = die->Tag();
3578
3579 // Check to see if we have already parsed this variable or constant?
3580 if (die->GetUserData() == NULL)
3581 {
3582 // We haven't already parsed it, lets do that now.
3583 if ((tag == DW_TAG_variable) ||
3584 (tag == DW_TAG_constant) ||
3585 (tag == DW_TAG_formal_parameter && sc.function))
3586 {
3587 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die));
3588 if (var_sp)
3589 {
3590 variables->AddVariable(var_sp);
3591 ++vars_added;
3592 }
3593 }
3594 }
3595
3596 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
3597
3598 if (!skip_children && parse_children && die->HasChildren())
3599 {
3600 vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), true, true);
3601 //vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), parse_siblings, parse_children);
3602 }
3603
3604 if (parse_siblings)
3605 die = die->GetSibling();
3606 else
3607 die = NULL;
3608 }
3609
3610 if (cc_variable_list)
3611 {
3612 cc_variable_list->AddVariables(variables.get());
3613 }
3614
3615 return vars_added;
3616}
3617
3618//------------------------------------------------------------------
3619// PluginInterface protocol
3620//------------------------------------------------------------------
3621const char *
3622SymbolFileDWARF::GetPluginName()
3623{
3624 return "SymbolFileDWARF";
3625}
3626
3627const char *
3628SymbolFileDWARF::GetShortPluginName()
3629{
3630 return GetPluginNameStatic();
3631}
3632
3633uint32_t
3634SymbolFileDWARF::GetPluginVersion()
3635{
3636 return 1;
3637}
3638
3639void
3640SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
3641{
3642}
3643
3644Error
3645SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
3646{
3647 Error error;
3648 error.SetErrorString("No plug-in command are currently supported.");
3649 return error;
3650}
3651
3652Log *
3653SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
3654{
3655 return NULL;
3656}
3657