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