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