blob: 7e4478deda7138f328d27e7406d453cbd4c1912f [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- SymbolFileDWARF.cpp ------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "SymbolFileDWARF.h"
11
12// Other libraries and framework includes
13#include "clang/AST/ASTConsumer.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclGroup.h"
17#include "clang/Basic/Builtins.h"
18#include "clang/Basic/IdentifierTable.h"
19#include "clang/Basic/LangOptions.h"
20#include "clang/Basic/SourceManager.h"
21#include "clang/Basic/TargetInfo.h"
22#include "clang/Basic/Specifiers.h"
23
24#include "lldb/Core/Module.h"
25#include "lldb/Core/PluginManager.h"
26#include "lldb/Core/RegularExpression.h"
27#include "lldb/Core/Scalar.h"
28#include "lldb/Core/Section.h"
29#include "lldb/Core/Timer.h"
30#include "lldb/Core/Value.h"
31
32#include "lldb/Symbol/Block.h"
33#include "lldb/Symbol/CompileUnit.h"
34#include "lldb/Symbol/LineTable.h"
35#include "lldb/Symbol/ObjectFile.h"
36#include "lldb/Symbol/SymbolVendor.h"
37#include "lldb/Symbol/VariableList.h"
38
39#include "DWARFCompileUnit.h"
40#include "DWARFDebugAbbrev.h"
41#include "DWARFDebugAranges.h"
42#include "DWARFDebugInfo.h"
43#include "DWARFDebugInfoEntry.h"
44#include "DWARFDebugLine.h"
45#include "DWARFDebugPubnames.h"
46#include "DWARFDebugRanges.h"
47#include "DWARFDIECollection.h"
48#include "DWARFFormValue.h"
49#include "DWARFLocationList.h"
50#include "LogChannelDWARF.h"
51
52#include <map>
53
54#define DIE_IS_BEING_PARSED ((void*)1)
55
56using namespace lldb;
57using namespace lldb_private;
58
59
Sean Callanan70a4f922010-08-06 00:32:49 +000060static AccessType
Greg Clayton84f80752010-07-22 18:30:50 +000061DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
Chris Lattner24943d22010-06-08 16:52:24 +000062{
63 switch (dwarf_accessibility)
64 {
Sean Callanan70a4f922010-08-06 00:32:49 +000065 case DW_ACCESS_public: return eAccessPublic;
66 case DW_ACCESS_private: return eAccessPrivate;
67 case DW_ACCESS_protected: return eAccessProtected;
Greg Clayton84f80752010-07-22 18:30:50 +000068 default: break;
Chris Lattner24943d22010-06-08 16:52:24 +000069 }
Sean Callanan70a4f922010-08-06 00:32:49 +000070 return eAccessNone;
Chris Lattner24943d22010-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 Clayton12bec712010-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 Lattner24943d22010-06-08 16:52:24 +0000156 m_name_to_global_die(),
157 m_name_to_type_die(),
158 m_indexed(false),
159// m_pubnames(),
Chris Lattner24943d22010-06-08 16:52:24 +0000160// m_pubbasetypes(),
Greg Clayton960d6a42010-08-03 00:35:52 +0000161 m_pubtypes(),
Chris Lattner24943d22010-06-08 16:52:24 +0000162 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 Clayton32a8c7e2010-07-21 22:54:26 +0000206 {
Chris Lattner24943d22010-06-08 16:52:24 +0000207 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000208 section_list = &section->GetChildren ();
209 }
Chris Lattner24943d22010-06-08 16:52:24 +0000210
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000211 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000212 if (section != NULL)
213 {
214 debug_info_file_size = section->GetByteSize();
215
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000216 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000217 if (section)
218 debug_abbrev_file_size = section->GetByteSize();
219 else
220 m_flags.Set (flagsGotDebugAbbrevData);
221
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000222 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000223 if (section)
224 debug_aranges_file_size = section->GetByteSize();
225 else
226 m_flags.Set (flagsGotDebugArangesData);
227
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000228 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000229 if (section)
230 debug_frame_file_size = section->GetByteSize();
231 else
232 m_flags.Set (flagsGotDebugFrameData);
233
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000234 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000235 if (section)
236 debug_line_file_size = section->GetByteSize();
237 else
238 m_flags.Set (flagsGotDebugLineData);
239
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000240 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000241 if (section)
242 debug_loc_file_size = section->GetByteSize();
243 else
244 m_flags.Set (flagsGotDebugLocData);
245
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000246 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000247 if (section)
248 debug_macinfo_file_size = section->GetByteSize();
249 else
250 m_flags.Set (flagsGotDebugMacInfoData);
251
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000252 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000253 if (section)
254 debug_pubnames_file_size = section->GetByteSize();
255 else
256 m_flags.Set (flagsGotDebugPubNamesData);
257
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000258 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000259 if (section)
260 debug_pubtypes_file_size = section->GetByteSize();
261 else
262 m_flags.Set (flagsGotDebugPubTypesData);
263
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000264 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000265 if (section)
266 debug_ranges_file_size = section->GetByteSize();
267 else
268 m_flags.Set (flagsGotDebugRangesData);
269
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000270 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner24943d22010-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 Clayton32a8c7e2010-07-21 22:54:26 +0000302SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner24943d22010-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 Clayton32a8c7e2010-07-21 22:54:26 +0000310 Section *section = section_list->FindSectionByType(sect_type, true).get();
311 if (section)
Chris Lattner24943d22010-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 Clayton32a8c7e2010-07-21 22:54:26 +0000332 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner24943d22010-06-08 16:52:24 +0000333}
334
335const DataExtractor&
336SymbolFileDWARF::get_debug_aranges_data()
337{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000338 return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
Chris Lattner24943d22010-06-08 16:52:24 +0000339}
340
341const DataExtractor&
342SymbolFileDWARF::get_debug_frame_data()
343{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000344 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner24943d22010-06-08 16:52:24 +0000345}
346
347const DataExtractor&
348SymbolFileDWARF::get_debug_info_data()
349{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000350 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner24943d22010-06-08 16:52:24 +0000351}
352
353const DataExtractor&
354SymbolFileDWARF::get_debug_line_data()
355{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000356 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner24943d22010-06-08 16:52:24 +0000357}
358
359const DataExtractor&
360SymbolFileDWARF::get_debug_loc_data()
361{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000362 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner24943d22010-06-08 16:52:24 +0000363}
364
365const DataExtractor&
366SymbolFileDWARF::get_debug_macinfo_data()
367{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000368 return GetCachedSectionData (flagsGotDebugMacInfoData, eSectionTypeDWARFDebugMacInfo, m_data_debug_macinfo);
Chris Lattner24943d22010-06-08 16:52:24 +0000369}
370
371const DataExtractor&
372SymbolFileDWARF::get_debug_pubnames_data()
373{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000374 return GetCachedSectionData (flagsGotDebugPubNamesData, eSectionTypeDWARFDebugPubNames, m_data_debug_pubnames);
Chris Lattner24943d22010-06-08 16:52:24 +0000375}
376
377const DataExtractor&
378SymbolFileDWARF::get_debug_pubtypes_data()
379{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000380 return GetCachedSectionData (flagsGotDebugPubTypesData, eSectionTypeDWARFDebugPubTypes, m_data_debug_pubtypes);
Chris Lattner24943d22010-06-08 16:52:24 +0000381}
382
383const DataExtractor&
384SymbolFileDWARF::get_debug_ranges_data()
385{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000386 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner24943d22010-06-08 16:52:24 +0000387}
388
389const DataExtractor&
390SymbolFileDWARF::get_debug_str_data()
391{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000392 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner24943d22010-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//
Greg Clayton960d6a42010-08-03 00:35:52 +0000618DWARFDebugPubnames*
619SymbolFileDWARF::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
Chris Lattner24943d22010-06-08 16:52:24 +0000636
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 Clayton9488b742010-07-28 02:04:09 +0000647 LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_language, 0);
Chris Lattner24943d22010-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 Clayton9488b742010-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 Lattner24943d22010-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 Clayton9488b742010-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 Lattner24943d22010-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 {
Chris Lattner24943d22010-06-08 16:52:24 +00001147 case DW_TAG_inlined_subroutine:
Jim Ingham0007dff2010-08-12 01:20:14 +00001148 case DW_TAG_subprogram:
Chris Lattner24943d22010-06-08 16:52:24 +00001149 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;
Jim Ingham0007dff2010-08-12 01:20:14 +00001163 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled_name, ranges,
1164 decl_file, decl_line, decl_column,
1165 call_file, call_line, call_column))
Chris Lattner24943d22010-06-08 16:52:24 +00001166 {
1167 if (tag == DW_TAG_subprogram)
1168 {
1169 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1170 subprogram_low_pc = ranges.LowestAddress(0);
1171 }
Jim Ingham0007dff2010-08-12 01:20:14 +00001172 else if (tag == DW_TAG_inlined_subroutine)
1173 {
1174 // We get called here for inlined subroutines in two ways.
1175 // The first time is when we are making the Function object
1176 // for this inlined concrete instance. Since we're creating a top level block at
1177 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1178 // adjust the containing address.
1179 // The second time is when we are parsing the blocks inside the function that contains
1180 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1181 // function the offset will be for that function.
1182 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1183 {
1184 subprogram_low_pc = ranges.LowestAddress(0);
1185 }
1186 }
1187
Chris Lattner24943d22010-06-08 16:52:24 +00001188 AddRangesToBlock (blocks, blockID, ranges, subprogram_low_pc);
1189
1190 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1191 {
1192 std::auto_ptr<Declaration> decl_ap;
1193 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Ingham0007dff2010-08-12 01:20:14 +00001194 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1195 decl_line, decl_column));
Chris Lattner24943d22010-06-08 16:52:24 +00001196
1197 std::auto_ptr<Declaration> call_ap;
1198 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Ingham0007dff2010-08-12 01:20:14 +00001199 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1200 call_line, call_column));
Chris Lattner24943d22010-06-08 16:52:24 +00001201
1202 blocks.SetInlinedFunctionInfo(blockID, name, mangled_name, decl_ap.get(), call_ap.get());
1203 }
1204
1205 ++blocks_added;
1206
1207 if (parse_children && die->HasChildren())
1208 {
Jim Ingham0007dff2010-08-12 01:20:14 +00001209 blocks_added += ParseFunctionBlocks(sc, blockID, dwarf_cu, die->GetFirstChild(),
1210 subprogram_low_pc, true, true);
Chris Lattner24943d22010-06-08 16:52:24 +00001211 }
1212 }
1213 }
1214 break;
1215 default:
1216 break;
1217 }
1218
1219 if (parse_siblings)
1220 die = die->GetSibling();
1221 else
1222 die = NULL;
1223 }
1224 return blocks_added;
1225}
1226
1227size_t
1228SymbolFileDWARF::ParseChildMembers
1229(
1230 const SymbolContext& sc,
1231 TypeSP& type_sp,
1232 const DWARFCompileUnit* dwarf_cu,
1233 const DWARFDebugInfoEntry *parent_die,
Greg Clayton9488b742010-07-28 02:04:09 +00001234 void *class_clang_type,
1235 const LanguageType class_language,
Chris Lattner24943d22010-06-08 16:52:24 +00001236 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1237 std::vector<int>& member_accessibilities,
Sean Callanan70a4f922010-08-06 00:32:49 +00001238 AccessType& default_accessibility,
Chris Lattner24943d22010-06-08 16:52:24 +00001239 bool &is_a_class
1240)
1241{
1242 if (parent_die == NULL)
1243 return 0;
1244
1245 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
1246
1247 size_t count = 0;
1248 const DWARFDebugInfoEntry *die;
1249 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1250 {
1251 dw_tag_t tag = die->Tag();
1252
1253 switch (tag)
1254 {
1255 case DW_TAG_member:
1256 {
1257 DWARFDebugInfoEntry::Attributes attributes;
1258 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
1259 if (num_attributes > 0)
1260 {
1261 Declaration decl;
1262 DWARFExpression location;
1263 const char *name = NULL;
1264 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callanan70a4f922010-08-06 00:32:49 +00001265 AccessType accessibility = eAccessNone;
Chris Lattner24943d22010-06-08 16:52:24 +00001266 off_t member_offset = 0;
1267 size_t byte_size = 0;
1268 size_t bit_offset = 0;
1269 size_t bit_size = 0;
1270 uint32_t i;
1271 for (i=0; i<num_attributes; ++i)
1272 {
1273 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1274 DWARFFormValue form_value;
1275 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1276 {
1277 switch (attr)
1278 {
1279 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1280 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1281 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1282 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1283 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1284 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1285 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1286 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1287 case DW_AT_data_member_location:
1288 if (form_value.BlockData())
1289 {
1290 Value initialValue(0);
1291 Value memberOffset(0);
1292 const DataExtractor& debug_info_data = get_debug_info_data();
1293 uint32_t block_length = form_value.Unsigned();
1294 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1295 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1296 {
1297 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1298 }
1299 }
1300 break;
1301
Greg Clayton84f80752010-07-22 18:30:50 +00001302 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Chris Lattner24943d22010-06-08 16:52:24 +00001303 case DW_AT_declaration:
1304 case DW_AT_description:
1305 case DW_AT_mutable:
1306 case DW_AT_visibility:
1307 default:
1308 case DW_AT_sibling:
1309 break;
1310 }
1311 }
1312 }
1313
1314 Type *member_type = ResolveTypeUID(encoding_uid);
1315 assert(member_type);
Sean Callanan70a4f922010-08-06 00:32:49 +00001316 if (accessibility == eAccessNone)
Chris Lattner24943d22010-06-08 16:52:24 +00001317 accessibility = default_accessibility;
1318 member_accessibilities.push_back(accessibility);
1319
1320 type_list->GetClangASTContext().AddFieldToRecordType (type_sp->GetOpaqueClangQualType(), name, member_type->GetOpaqueClangQualType(), accessibility, bit_size);
1321 }
1322 }
1323 break;
1324
1325 case DW_TAG_subprogram:
1326 {
1327 is_a_class = true;
Sean Callanan70a4f922010-08-06 00:32:49 +00001328 if (default_accessibility == eAccessNone)
1329 default_accessibility = eAccessPrivate;
Chris Lattner24943d22010-06-08 16:52:24 +00001330 // TODO: implement DW_TAG_subprogram type parsing
1331// UserDefTypeChildInfo method_info(die->GetOffset());
1332//
1333// FunctionSP func_sp (sc.comp_unit->FindFunctionByUID (die->GetOffset()));
1334// if (func_sp.get() == NULL)
1335// ParseCompileUnitFunction(sc, dwarf_cu, die);
1336//
1337// method_info.SetEncodingTypeUID(die->GetOffset());
1338// struct_udt->AddMethod(method_info);
1339 }
1340 break;
1341
1342 case DW_TAG_inheritance:
1343 {
1344 is_a_class = true;
Sean Callanan70a4f922010-08-06 00:32:49 +00001345 if (default_accessibility == eAccessNone)
1346 default_accessibility = eAccessPrivate;
Chris Lattner24943d22010-06-08 16:52:24 +00001347 // TODO: implement DW_TAG_inheritance type parsing
1348 DWARFDebugInfoEntry::Attributes attributes;
1349 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
1350 if (num_attributes > 0)
1351 {
1352 Declaration decl;
1353 DWARFExpression location;
1354 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callanan70a4f922010-08-06 00:32:49 +00001355 AccessType accessibility = default_accessibility;
Chris Lattner24943d22010-06-08 16:52:24 +00001356 bool is_virtual = false;
1357 bool is_base_of_class = true;
1358 off_t member_offset = 0;
1359 uint32_t i;
1360 for (i=0; i<num_attributes; ++i)
1361 {
1362 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1363 DWARFFormValue form_value;
1364 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1365 {
1366 switch (attr)
1367 {
1368 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1369 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1370 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1371 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1372 case DW_AT_data_member_location:
1373 if (form_value.BlockData())
1374 {
1375 Value initialValue(0);
1376 Value memberOffset(0);
1377 const DataExtractor& debug_info_data = get_debug_info_data();
1378 uint32_t block_length = form_value.Unsigned();
1379 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1380 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1381 {
1382 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1383 }
1384 }
1385 break;
1386
1387 case DW_AT_accessibility:
Greg Clayton84f80752010-07-22 18:30:50 +00001388 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner24943d22010-06-08 16:52:24 +00001389 break;
1390
1391 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1392 default:
1393 case DW_AT_sibling:
1394 break;
1395 }
1396 }
1397 }
1398
1399 Type *base_class_dctype = ResolveTypeUID(encoding_uid);
1400 assert(base_class_dctype);
Greg Clayton9488b742010-07-28 02:04:09 +00001401
1402 if (class_language == eLanguageTypeObjC)
1403 {
1404 type_list->GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_dctype->GetOpaqueClangQualType());
1405 }
1406 else
1407 {
1408 base_classes.push_back (type_list->GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetOpaqueClangQualType(), accessibility, is_virtual, is_base_of_class));
1409 assert(base_classes.back());
1410 }
Chris Lattner24943d22010-06-08 16:52:24 +00001411 }
1412 }
1413 break;
1414
1415 default:
1416 break;
1417 }
1418 }
1419 return count;
1420}
1421
1422
1423clang::DeclContext*
1424SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1425{
1426 DWARFDebugInfo* debug_info = DebugInfo();
1427 if (debug_info)
1428 {
1429 DWARFCompileUnitSP cu_sp;
1430 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1431 if (die)
1432 return GetClangDeclContextForDIE (cu_sp.get(), die);
1433 }
1434 return NULL;
1435}
1436
1437Type*
1438SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid)
1439{
1440 DWARFDebugInfo* debug_info = DebugInfo();
1441 if (debug_info)
1442 {
1443 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, NULL);
1444 if (type_die != NULL)
1445 {
1446 void *type = type_die->GetUserData();
1447 if (type == NULL)
1448 {
1449 DWARFCompileUnitSP cu_sp;
1450 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1451 if (die != NULL)
1452 {
1453 TypeSP owning_type_sp;
1454 TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, 0, 0));
1455 }
1456 type = type_die->GetUserData();
1457 }
1458 if (type != DIE_IS_BEING_PARSED)
1459 return (Type *)type;
1460 }
1461 }
1462 return NULL;
1463}
1464
1465CompileUnit*
1466SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx)
1467{
1468 // Check if the symbol vendor already knows about this compile unit?
1469 if (cu->GetUserData() == NULL)
1470 {
1471 // The symbol vendor doesn't know about this compile unit, we
1472 // need to parse and add it to the symbol vendor object.
1473 CompUnitSP dc_cu;
1474 ParseCompileUnit(cu, dc_cu);
1475 if (dc_cu.get())
1476 {
1477 // Figure out the compile unit index if we weren't given one
1478 if (cu_idx == UINT_MAX)
1479 DebugInfo()->GetCompileUnit(cu->GetOffset(), &cu_idx);
1480
1481 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
1482 }
1483 }
1484 return (CompileUnit*)cu->GetUserData();
1485}
1486
1487bool
1488SymbolFileDWARF::GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
1489{
1490 sc.Clear();
1491 // Check if the symbol vendor already knows about this compile unit?
1492 sc.module_sp = m_obj_file->GetModule()->GetSP();
1493 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
1494
1495 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1496 if (sc.function == NULL)
1497 sc.function = ParseCompileUnitFunction(sc, cu, func_die);
1498
1499 return sc.function != NULL;
1500}
1501
1502uint32_t
1503SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1504{
1505 Timer scoped_timer(__PRETTY_FUNCTION__,
1506 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1507 so_addr.GetSection(),
1508 so_addr.GetOffset(),
1509 resolve_scope);
1510 uint32_t resolved = 0;
1511 if (resolve_scope & ( eSymbolContextCompUnit |
1512 eSymbolContextFunction |
1513 eSymbolContextBlock |
1514 eSymbolContextLineEntry))
1515 {
1516 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1517
1518 DWARFDebugAranges* debug_aranges = DebugAranges();
1519 DWARFDebugInfo* debug_info = DebugInfo();
1520 if (debug_aranges)
1521 {
1522 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1523 if (cu_offset != DW_INVALID_OFFSET)
1524 {
1525 uint32_t cu_idx;
1526 DWARFCompileUnit* cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1527 if (cu)
1528 {
1529 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1530 assert(sc.comp_unit != NULL);
1531 resolved |= eSymbolContextCompUnit;
1532
1533 if (resolve_scope & eSymbolContextLineEntry)
1534 {
1535 LineTable *line_table = sc.comp_unit->GetLineTable();
1536 if (line_table == NULL)
1537 {
1538 if (ParseCompileUnitLineTable(sc))
1539 line_table = sc.comp_unit->GetLineTable();
1540 }
1541 if (line_table != NULL)
1542 {
1543 if (so_addr.IsLinkedAddress())
1544 {
1545 Address linked_addr (so_addr);
1546 linked_addr.ResolveLinkedAddress();
1547 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1548 {
1549 resolved |= eSymbolContextLineEntry;
1550 }
1551 }
1552 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1553 {
1554 resolved |= eSymbolContextLineEntry;
1555 }
1556 }
1557 }
1558
1559 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1560 {
1561 DWARFDebugInfoEntry *function_die = NULL;
1562 DWARFDebugInfoEntry *block_die = NULL;
1563 if (resolve_scope & eSymbolContextBlock)
1564 {
1565 cu->LookupAddress(file_vm_addr, &function_die, &block_die);
1566 }
1567 else
1568 {
1569 cu->LookupAddress(file_vm_addr, &function_die, NULL);
1570 }
1571
1572 if (function_die != NULL)
1573 {
1574 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1575 if (sc.function == NULL)
1576 sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1577 }
1578
1579 if (sc.function != NULL)
1580 {
1581 resolved |= eSymbolContextFunction;
1582
1583 if (resolve_scope & eSymbolContextBlock)
1584 {
1585 BlockList& blocks = sc.function->GetBlocks(true);
1586
1587 if (block_die != NULL)
1588 sc.block = blocks.GetBlockByID(block_die->GetOffset());
1589 else
1590 sc.block = blocks.GetBlockByID(function_die->GetOffset());
1591 if (sc.block)
1592 resolved |= eSymbolContextBlock;
1593 }
1594 }
1595 }
1596 }
1597 }
1598 }
1599 }
1600 return resolved;
1601}
1602
1603
1604
1605uint32_t
1606SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1607{
1608 const uint32_t prev_size = sc_list.GetSize();
1609 if (resolve_scope & eSymbolContextCompUnit)
1610 {
1611 DWARFDebugInfo* debug_info = DebugInfo();
1612 if (debug_info)
1613 {
1614 uint32_t cu_idx;
1615 DWARFCompileUnit* cu = NULL;
1616
1617 for (cu_idx = 0; (cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
1618 {
1619 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1620 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1621 if (check_inlines || file_spec_matches_cu_file_spec)
1622 {
1623 SymbolContext sc (m_obj_file->GetModule());
1624 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1625 assert(sc.comp_unit != NULL);
1626
1627 uint32_t file_idx = UINT32_MAX;
1628
1629 // If we are looking for inline functions only and we don't
1630 // find it in the support files, we are done.
1631 if (check_inlines)
1632 {
1633 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1634 if (file_idx == UINT32_MAX)
1635 continue;
1636 }
1637
1638 if (line != 0)
1639 {
1640 LineTable *line_table = sc.comp_unit->GetLineTable();
1641
1642 if (line_table != NULL && line != 0)
1643 {
1644 // We will have already looked up the file index if
1645 // we are searching for inline entries.
1646 if (!check_inlines)
1647 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1648
1649 if (file_idx != UINT32_MAX)
1650 {
1651 uint32_t found_line;
1652 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1653 found_line = sc.line_entry.line;
1654
1655 while (line_idx != UINT_MAX)
1656 {
1657 sc.function = NULL;
1658 sc.block = NULL;
1659 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1660 {
1661 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1662 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1663 {
1664 DWARFDebugInfoEntry *function_die = NULL;
1665 DWARFDebugInfoEntry *block_die = NULL;
1666 cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
1667
1668 if (function_die != NULL)
1669 {
1670 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1671 if (sc.function == NULL)
1672 sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1673 }
1674
1675 if (sc.function != NULL)
1676 {
1677 BlockList& blocks = sc.function->GetBlocks(true);
1678
1679 if (block_die != NULL)
1680 sc.block = blocks.GetBlockByID(block_die->GetOffset());
1681 else
1682 sc.block = blocks.GetBlockByID(function_die->GetOffset());
1683 }
1684 }
1685 }
1686
1687 sc_list.Append(sc);
1688 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1689 }
1690 }
1691 }
1692 else if (file_spec_matches_cu_file_spec && !check_inlines)
1693 {
1694 // only append the context if we aren't looking for inline call sites
1695 // by file and line and if the file spec matches that of the compile unit
1696 sc_list.Append(sc);
1697 }
1698 }
1699 else if (file_spec_matches_cu_file_spec && !check_inlines)
1700 {
1701 // only append the context if we aren't looking for inline call sites
1702 // by file and line and if the file spec matches that of the compile unit
1703 sc_list.Append(sc);
1704 }
1705
1706 if (!check_inlines)
1707 break;
1708 }
1709 }
1710 }
1711 }
1712 return sc_list.GetSize() - prev_size;
1713}
1714
1715void
1716SymbolFileDWARF::Index ()
1717{
1718 if (m_indexed)
1719 return;
1720 m_indexed = true;
1721 Timer scoped_timer (__PRETTY_FUNCTION__,
1722 "SymbolFileDWARF::Index (%s)",
1723 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1724
1725 DWARFDebugInfo* debug_info = DebugInfo();
1726 if (debug_info)
1727 {
1728 uint32_t cu_idx = 0;
1729 const uint32_t num_compile_units = GetNumCompileUnits();
1730 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1731 {
1732 DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
1733
1734 bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1;
1735
Greg Clayton12bec712010-06-28 21:30:43 +00001736 cu->Index (m_base_name_to_function_die,
1737 m_full_name_to_function_die,
1738 m_method_name_to_function_die,
1739 m_selector_name_to_function_die,
Chris Lattner24943d22010-06-08 16:52:24 +00001740 m_name_to_global_die,
1741 m_name_to_type_die);
1742
1743 // Keep memory down by clearing DIEs if this generate function
1744 // caused them to be parsed
1745 if (clear_dies)
1746 cu->ClearDIEs (true);
1747 }
1748
Greg Clayton12bec712010-06-28 21:30:43 +00001749 m_base_name_to_function_die.Sort();
1750 m_full_name_to_function_die.Sort();
1751 m_method_name_to_function_die.Sort();
1752 m_selector_name_to_function_die.Sort();
Chris Lattner24943d22010-06-08 16:52:24 +00001753 m_name_to_global_die.Sort();
1754 m_name_to_type_die.Sort();
1755 }
1756}
1757
1758uint32_t
1759SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1760{
1761 std::vector<dw_offset_t> die_offsets;
1762
1763 // If we aren't appending the results to this list, then clear the list
1764 if (!append)
1765 variables.Clear();
1766
1767 // Remember how many variables are in the list before we search in case
1768 // we are appending the results to a variable list.
1769 const uint32_t original_size = variables.GetSize();
1770
1771 // Index the DWARF if we haven't already
1772 if (!m_indexed)
1773 Index ();
1774
1775 const UniqueCStringMap<dw_offset_t>::Entry *entry;
1776
1777 for (entry = m_name_to_global_die.FindFirstValueForName (name.AsCString());
1778 entry != NULL;
1779 entry = m_name_to_global_die.FindNextValueForName (name.AsCString(), entry))
1780 {
1781 DWARFCompileUnitSP cu_sp;
1782 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp);
1783 DWARFCompileUnit* cu = cu_sp.get();
1784 if (die)
1785 {
1786 SymbolContext sc;
1787 sc.module_sp = m_obj_file->GetModule()->GetSP();
1788 assert (sc.module_sp);
1789
1790 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
1791 assert(sc.comp_unit != NULL);
1792
1793 ParseVariables(sc, cu_sp.get(), die, false, false, &variables);
1794
1795 if (variables.GetSize() - original_size >= max_matches)
1796 break;
1797 }
1798 }
1799
1800 // Return the number of variable that were appended to the list
1801 return variables.GetSize() - original_size;
1802}
1803
1804uint32_t
1805SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1806{
1807 std::vector<dw_offset_t> die_offsets;
1808
1809 // If we aren't appending the results to this list, then clear the list
1810 if (!append)
1811 variables.Clear();
1812
1813 // Remember how many variables are in the list before we search in case
1814 // we are appending the results to a variable list.
1815 const uint32_t original_size = variables.GetSize();
1816
1817 // Index the DWARF if we haven't already
1818 if (!m_indexed)
1819 Index ();
1820
1821 // Create the pubnames information so we can quickly lookup external symbols by name
1822 const size_t num_entries = m_name_to_global_die.GetSize();
1823 for (size_t i=0; i<num_entries; i++)
1824 {
1825 if (!regex.Execute(m_name_to_global_die.GetCStringAtIndex (i)))
1826 continue;
1827
1828 const dw_offset_t die_offset = *m_name_to_global_die.GetValueAtIndex (i);
1829
1830 DWARFCompileUnitSP cu_sp;
1831 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp);
1832 DWARFCompileUnit* cu = cu_sp.get();
1833 if (die)
1834 {
1835 SymbolContext sc;
1836 sc.module_sp = m_obj_file->GetModule()->GetSP();
1837 assert (sc.module_sp);
1838
1839
1840 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
1841 assert(sc.comp_unit != NULL);
1842
1843 ParseVariables(sc, cu_sp.get(), die, false, false, &variables);
1844
1845 if (variables.GetSize() - original_size >= max_matches)
1846 break;
1847 }
1848 }
1849
1850 // Return the number of variable that were appended to the list
1851 return variables.GetSize() - original_size;
1852}
1853
1854
Greg Clayton12bec712010-06-28 21:30:43 +00001855void
1856SymbolFileDWARF::FindFunctions
1857(
1858 const ConstString &name,
1859 UniqueCStringMap<dw_offset_t> &name_to_die,
1860 SymbolContextList& sc_list
1861)
Chris Lattner24943d22010-06-08 16:52:24 +00001862{
Chris Lattner24943d22010-06-08 16:52:24 +00001863 const UniqueCStringMap<dw_offset_t>::Entry *entry;
1864
1865 SymbolContext sc;
Greg Clayton12bec712010-06-28 21:30:43 +00001866 for (entry = name_to_die.FindFirstValueForName (name.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001867 entry != NULL;
Greg Clayton12bec712010-06-28 21:30:43 +00001868 entry = name_to_die.FindNextValueForName (name.AsCString(), entry))
Chris Lattner24943d22010-06-08 16:52:24 +00001869 {
1870 DWARFCompileUnitSP cu_sp;
1871 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp);
1872 if (die)
1873 {
1874 if (GetFunction (cu_sp.get(), die, sc))
1875 {
1876 // We found the function, so we should find the line table
1877 // and line table entry as well
1878 LineTable *line_table = sc.comp_unit->GetLineTable();
1879 if (line_table == NULL)
1880 {
1881 if (ParseCompileUnitLineTable(sc))
1882 line_table = sc.comp_unit->GetLineTable();
1883 }
1884 if (line_table != NULL)
1885 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1886
1887 sc_list.Append(sc);
1888 }
1889 }
1890 }
1891
Greg Clayton12bec712010-06-28 21:30:43 +00001892}
1893
1894uint32_t
1895SymbolFileDWARF::FindFunctions
1896(
1897 const ConstString &name,
1898 uint32_t name_type_mask,
1899 bool append,
1900 SymbolContextList& sc_list
1901)
1902{
1903 Timer scoped_timer (__PRETTY_FUNCTION__,
1904 "SymbolFileDWARF::FindFunctions (name = '%s')",
1905 name.AsCString());
1906
1907 std::vector<dw_offset_t> die_offsets;
1908
1909 // If we aren't appending the results to this list, then clear the list
1910 if (!append)
1911 sc_list.Clear();
1912
1913 // Remember how many sc_list are in the list before we search in case
1914 // we are appending the results to a variable list.
1915 uint32_t original_size = sc_list.GetSize();
1916
1917 // Index the DWARF if we haven't already
1918 if (!m_indexed)
1919 Index ();
1920
1921 if (name_type_mask & eFunctionNameTypeBase)
1922 FindFunctions (name, m_base_name_to_function_die, sc_list);
1923
1924 if (name_type_mask & eFunctionNameTypeFull)
1925 FindFunctions (name, m_full_name_to_function_die, sc_list);
1926
1927 if (name_type_mask & eFunctionNameTypeMethod)
1928 FindFunctions (name, m_method_name_to_function_die, sc_list);
1929
1930 if (name_type_mask & eFunctionNameTypeSelector)
1931 FindFunctions (name, m_selector_name_to_function_die, sc_list);
1932
Chris Lattner24943d22010-06-08 16:52:24 +00001933 // Return the number of variable that were appended to the list
1934 return sc_list.GetSize() - original_size;
1935}
1936
1937
1938uint32_t
1939SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
1940{
1941 Timer scoped_timer (__PRETTY_FUNCTION__,
1942 "SymbolFileDWARF::FindFunctions (regex = '%s')",
1943 regex.GetText());
1944
1945 std::vector<dw_offset_t> die_offsets;
1946
1947 // If we aren't appending the results to this list, then clear the list
1948 if (!append)
1949 sc_list.Clear();
1950
1951 // Remember how many sc_list are in the list before we search in case
1952 // we are appending the results to a variable list.
1953 uint32_t original_size = sc_list.GetSize();
1954
1955 // Index the DWARF if we haven't already
1956 if (!m_indexed)
1957 Index ();
1958
1959 // Create the pubnames information so we can quickly lookup external symbols by name
1960 // Create the pubnames information so we can quickly lookup external symbols by name
Greg Clayton12bec712010-06-28 21:30:43 +00001961 const size_t num_entries = m_full_name_to_function_die.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +00001962 SymbolContext sc;
1963 for (size_t i=0; i<num_entries; i++)
1964 {
Greg Clayton12bec712010-06-28 21:30:43 +00001965 if (!regex.Execute(m_full_name_to_function_die.GetCStringAtIndex (i)))
Chris Lattner24943d22010-06-08 16:52:24 +00001966 continue;
1967
Greg Clayton12bec712010-06-28 21:30:43 +00001968 const dw_offset_t die_offset = *m_full_name_to_function_die.GetValueAtIndex (i);
Chris Lattner24943d22010-06-08 16:52:24 +00001969
1970 DWARFCompileUnitSP cu_sp;
1971 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp);
1972 if (die)
1973 {
1974 if (GetFunction (cu_sp.get(), die, sc))
1975 {
1976 // We found the function, so we should find the line table
1977 // and line table entry as well
1978 LineTable *line_table = sc.comp_unit->GetLineTable();
1979 if (line_table == NULL)
1980 {
1981 if (ParseCompileUnitLineTable(sc))
1982 line_table = sc.comp_unit->GetLineTable();
1983 }
1984 if (line_table != NULL)
1985 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1986
1987
1988 sc_list.Append(sc);
1989 }
1990 }
1991 }
1992
1993 // Return the number of variable that were appended to the list
1994 return sc_list.GetSize() - original_size;
1995}
1996
Chris Lattner24943d22010-06-08 16:52:24 +00001997uint32_t
Greg Clayton960d6a42010-08-03 00:35:52 +00001998SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner24943d22010-06-08 16:52:24 +00001999{
2000 // If we aren't appending the results to this list, then clear the list
2001 if (!append)
2002 types.Clear();
2003
2004 // Create the pubnames information so we can quickly lookup external symbols by name
2005 DWARFDebugPubnames* pubtypes = DebugPubtypes();
Greg Clayton960d6a42010-08-03 00:35:52 +00002006
Chris Lattner24943d22010-06-08 16:52:24 +00002007 if (pubtypes)
2008 {
2009 std::vector<dw_offset_t> die_offsets;
2010 if (!pubtypes->Find(name.AsCString(), false, die_offsets))
2011 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002012// DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes();
2013// if (pub_base_types && !pub_base_types->Find(name.AsCString(), false, die_offsets))
Chris Lattner24943d22010-06-08 16:52:24 +00002014 return 0;
2015 }
Greg Clayton960d6a42010-08-03 00:35:52 +00002016 return FindTypes(die_offsets, max_matches, types);
Chris Lattner24943d22010-06-08 16:52:24 +00002017 }
2018 return 0;
2019}
2020
2021
Greg Clayton960d6a42010-08-03 00:35:52 +00002022//uint32_t
2023//SymbolFileDWARF::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types)
2024//{
2025// // If we aren't appending the results to this list, then clear the list
2026// if (!append)
2027// types.Clear();
2028//
2029// // Create the pubnames information so we can quickly lookup external symbols by name
2030// DWARFDebugPubnames* pubtypes = DebugPubtypes();
2031// if (pubtypes)
2032// {
2033// std::vector<dw_offset_t> die_offsets;
2034// if (!pubtypes->Find(regex, die_offsets))
2035// {
2036// DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes();
2037// if (pub_base_types && !pub_base_types->Find(regex, die_offsets))
2038// return 0;
2039// }
2040//
2041// return FindTypes(die_offsets, max_matches, encoding, udt_uid, types);
2042// }
2043//
2044// return 0;
2045//}
2046//
Chris Lattner24943d22010-06-08 16:52:24 +00002047
2048
2049uint32_t
Greg Clayton960d6a42010-08-03 00:35:52 +00002050SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner24943d22010-06-08 16:52:24 +00002051{
2052 // Remember how many sc_list are in the list before we search in case
2053 // we are appending the results to a variable list.
Greg Clayton960d6a42010-08-03 00:35:52 +00002054 uint32_t original_size = types.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +00002055
2056 const uint32_t num_die_offsets = die_offsets.size();
2057 // Parse all of the types we found from the pubtypes matches
2058 uint32_t i;
2059 uint32_t num_matches = 0;
2060 for (i = 0; i < num_die_offsets; ++i)
2061 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002062 Type *matching_type = ResolveTypeUID (die_offsets[i]);
2063 if (matching_type)
Chris Lattner24943d22010-06-08 16:52:24 +00002064 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002065 // We found a type pointer, now find the shared pointer form our type list
2066 TypeSP type_sp (m_obj_file->GetModule()->GetTypeList()->FindType(matching_type->GetID()));
2067 assert (type_sp.get() != NULL);
2068 types.InsertUnique (type_sp);
2069 ++num_matches;
2070 if (num_matches >= max_matches)
2071 break;
Chris Lattner24943d22010-06-08 16:52:24 +00002072 }
2073 }
2074
2075 // Return the number of variable that were appended to the list
Greg Clayton960d6a42010-08-03 00:35:52 +00002076 return types.GetSize() - original_size;
Chris Lattner24943d22010-06-08 16:52:24 +00002077}
2078
Chris Lattner24943d22010-06-08 16:52:24 +00002079
2080size_t
2081SymbolFileDWARF::ParseChildParameters
2082(
2083 const SymbolContext& sc,
2084 TypeSP& type_sp,
2085 const DWARFCompileUnit* dwarf_cu,
2086 const DWARFDebugInfoEntry *parent_die,
2087 TypeList* type_list,
2088 std::vector<void *>& function_param_types,
2089 std::vector<clang::ParmVarDecl*>& function_param_decls
2090)
2091{
2092 if (parent_die == NULL)
2093 return 0;
2094
2095 size_t count = 0;
2096 const DWARFDebugInfoEntry *die;
2097 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2098 {
2099 dw_tag_t tag = die->Tag();
2100 switch (tag)
2101 {
2102 case DW_TAG_formal_parameter:
2103 {
2104 DWARFDebugInfoEntry::Attributes attributes;
2105 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2106 if (num_attributes > 0)
2107 {
2108 const char *name = NULL;
2109 Declaration decl;
2110 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
2111 // one of None, Auto, Register, Extern, Static, PrivateExtern
2112
2113 clang::VarDecl::StorageClass storage = clang::VarDecl::None;
2114 uint32_t i;
2115 for (i=0; i<num_attributes; ++i)
2116 {
2117 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2118 DWARFFormValue form_value;
2119 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2120 {
2121 switch (attr)
2122 {
2123 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2124 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2125 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2126 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2127 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
2128 case DW_AT_location:
2129 // if (form_value.BlockData())
2130 // {
2131 // const DataExtractor& debug_info_data = debug_info();
2132 // uint32_t block_length = form_value.Unsigned();
2133 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2134 // }
2135 // else
2136 // {
2137 // }
2138 // break;
2139 case DW_AT_artificial:
2140 case DW_AT_const_value:
2141 case DW_AT_default_value:
2142 case DW_AT_description:
2143 case DW_AT_endianity:
2144 case DW_AT_is_optional:
2145 case DW_AT_segment:
2146 case DW_AT_variable_parameter:
2147 default:
2148 case DW_AT_abstract_origin:
2149 case DW_AT_sibling:
2150 break;
2151 }
2152 }
2153 }
2154 Type *dc_type = ResolveTypeUID(param_type_die_offset);
2155 if (dc_type)
2156 {
2157 function_param_types.push_back (dc_type->GetOpaqueClangQualType());
2158
2159 clang::ParmVarDecl *param_var_decl = type_list->GetClangASTContext().CreateParmeterDeclaration (name, dc_type->GetOpaqueClangQualType(), storage);
2160 assert(param_var_decl);
2161 function_param_decls.push_back(param_var_decl);
2162 }
2163 }
2164 }
2165 break;
2166
2167 default:
2168 break;
2169 }
2170 }
2171 return count;
2172}
2173
2174size_t
2175SymbolFileDWARF::ParseChildEnumerators
2176(
2177 const SymbolContext& sc,
2178 TypeSP& type_sp,
2179 void * enumerator_qual_type,
2180 uint32_t enumerator_byte_size,
2181 const DWARFCompileUnit* dwarf_cu,
2182 const DWARFDebugInfoEntry *parent_die
2183)
2184{
2185 if (parent_die == NULL)
2186 return 0;
2187
2188 size_t enumerators_added = 0;
2189 const DWARFDebugInfoEntry *die;
2190 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2191 {
2192 const dw_tag_t tag = die->Tag();
2193 if (tag == DW_TAG_enumerator)
2194 {
2195 DWARFDebugInfoEntry::Attributes attributes;
2196 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2197 if (num_child_attributes > 0)
2198 {
2199 const char *name = NULL;
2200 bool got_value = false;
2201 int64_t enum_value = 0;
2202 Declaration decl;
2203
2204 uint32_t i;
2205 for (i=0; i<num_child_attributes; ++i)
2206 {
2207 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2208 DWARFFormValue form_value;
2209 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2210 {
2211 switch (attr)
2212 {
2213 case DW_AT_const_value:
2214 got_value = true;
2215 enum_value = form_value.Unsigned();
2216 break;
2217
2218 case DW_AT_name:
2219 name = form_value.AsCString(&get_debug_str_data());
2220 break;
2221
2222 case DW_AT_description:
2223 default:
2224 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2225 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2226 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2227 case DW_AT_sibling:
2228 break;
2229 }
2230 }
2231 }
2232
2233 if (name && name[0] && got_value)
2234 {
2235 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2236 type_list->GetClangASTContext().AddEnumerationValueToEnumerationType (type_sp->GetOpaqueClangQualType(), enumerator_qual_type, decl, name, enum_value, enumerator_byte_size * 8);
2237 ++enumerators_added;
2238 }
2239 }
2240 }
2241 }
2242 return enumerators_added;
2243}
2244
2245void
2246SymbolFileDWARF::ParseChildArrayInfo
2247(
2248 const SymbolContext& sc,
2249 const DWARFCompileUnit* dwarf_cu,
2250 const DWARFDebugInfoEntry *parent_die,
2251 int64_t& first_index,
2252 std::vector<uint64_t>& element_orders,
2253 uint32_t& byte_stride,
2254 uint32_t& bit_stride
2255)
2256{
2257 if (parent_die == NULL)
2258 return;
2259
2260 const DWARFDebugInfoEntry *die;
2261 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2262 {
2263 const dw_tag_t tag = die->Tag();
2264 switch (tag)
2265 {
2266 case DW_TAG_enumerator:
2267 {
2268 DWARFDebugInfoEntry::Attributes attributes;
2269 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2270 if (num_child_attributes > 0)
2271 {
2272 const char *name = NULL;
2273 bool got_value = false;
2274 int64_t enum_value = 0;
2275
2276 uint32_t i;
2277 for (i=0; i<num_child_attributes; ++i)
2278 {
2279 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2280 DWARFFormValue form_value;
2281 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2282 {
2283 switch (attr)
2284 {
2285 case DW_AT_const_value:
2286 got_value = true;
2287 enum_value = form_value.Unsigned();
2288 break;
2289
2290 case DW_AT_name:
2291 name = form_value.AsCString(&get_debug_str_data());
2292 break;
2293
2294 case DW_AT_description:
2295 default:
2296 case DW_AT_decl_file:
2297 case DW_AT_decl_line:
2298 case DW_AT_decl_column:
2299 case DW_AT_sibling:
2300 break;
2301 }
2302 }
2303 }
2304 }
2305 }
2306 break;
2307
2308 case DW_TAG_subrange_type:
2309 {
2310 DWARFDebugInfoEntry::Attributes attributes;
2311 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2312 if (num_child_attributes > 0)
2313 {
2314 const char *name = NULL;
2315 bool got_value = false;
2316 uint64_t byte_size = 0;
2317 int64_t enum_value = 0;
2318 uint64_t num_elements = 0;
2319 uint64_t lower_bound = 0;
2320 uint64_t upper_bound = 0;
2321 uint32_t i;
2322 for (i=0; i<num_child_attributes; ++i)
2323 {
2324 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2325 DWARFFormValue form_value;
2326 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2327 {
2328 switch (attr)
2329 {
2330 case DW_AT_const_value:
2331 got_value = true;
2332 enum_value = form_value.Unsigned();
2333 break;
2334
2335 case DW_AT_name:
2336 name = form_value.AsCString(&get_debug_str_data());
2337 break;
2338
2339 case DW_AT_count:
2340 num_elements = form_value.Unsigned();
2341 break;
2342
2343 case DW_AT_bit_stride:
2344 bit_stride = form_value.Unsigned();
2345 break;
2346
2347 case DW_AT_byte_stride:
2348 byte_stride = form_value.Unsigned();
2349 break;
2350
2351 case DW_AT_byte_size:
2352 byte_size = form_value.Unsigned();
2353 break;
2354
2355 case DW_AT_lower_bound:
2356 lower_bound = form_value.Unsigned();
2357 break;
2358
2359 case DW_AT_upper_bound:
2360 upper_bound = form_value.Unsigned();
2361 break;
2362
2363 default:
2364 //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
2365
2366 case DW_AT_abstract_origin:
2367 case DW_AT_accessibility:
2368 case DW_AT_allocated:
2369 case DW_AT_associated:
2370 case DW_AT_data_location:
2371 case DW_AT_declaration:
2372 case DW_AT_description:
2373 case DW_AT_sibling:
2374 case DW_AT_threads_scaled:
2375 case DW_AT_type:
2376 case DW_AT_visibility:
2377 break;
2378 }
2379 }
2380 }
2381
2382 if (upper_bound > lower_bound)
2383 num_elements = upper_bound - lower_bound + 1;
2384
2385 if (num_elements > 0)
2386 element_orders.push_back (num_elements);
2387 }
2388 }
2389 break;
2390 }
2391 }
2392}
2393
2394Type*
2395SymbolFileDWARF::GetUniquedTypeForDIEOffset(dw_offset_t type_die_offset, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx, bool safe)
2396{
2397 if (type_die_offset != DW_INVALID_OFFSET)
2398 {
2399 DWARFCompileUnitSP cu_sp;
2400 const DWARFDebugInfoEntry* type_die = DebugInfo()->GetDIEPtr(type_die_offset, &cu_sp);
2401 assert(type_die != NULL);
2402 GetTypeForDIE(cu_sp.get(), type_die, owning_type_sp, child_type, idx);
2403 // Return the uniqued type if there is one
2404 Type* type = (Type*)type_die->GetUserData();
2405 if (type == DIE_IS_BEING_PARSED && safe)
2406 return NULL;
2407 return type;
2408 }
2409 return NULL;
2410}
2411
2412TypeSP
2413SymbolFileDWARF::GetTypeForDIE(DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx)
2414{
2415 TypeSP type_sp;
2416 if (die != NULL)
2417 {
2418 assert(cu != NULL);
2419 Type *type_ptr = (Type *)die->GetUserData();
2420 if (type_ptr == NULL)
2421 {
2422 SymbolContext sc(GetCompUnitForDWARFCompUnit(cu));
2423 bool type_is_new = false;
2424 type_sp = ParseType(sc, cu, die, type_is_new);
2425 type_ptr = (Type *)die->GetUserData();
2426 if (owning_type_sp.get() == NULL)
2427 owning_type_sp = type_sp;
2428 }
2429 else if (type_ptr != DIE_IS_BEING_PARSED)
2430 {
2431 // Grab the existing type from the master types lists
2432 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(type_ptr->GetID());
2433 }
2434
2435 }
2436 return type_sp;
2437}
2438
2439clang::DeclContext *
2440SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2441{
2442 if (die_offset != DW_INVALID_OFFSET)
2443 {
2444 DWARFCompileUnitSP cu_sp;
2445 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2446 return GetClangDeclContextForDIE (cu_sp.get(), die);
2447 }
2448 return NULL;
2449}
2450
2451
2452
2453clang::DeclContext *
2454SymbolFileDWARF::GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
2455{
2456 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2457 if (pos != m_die_to_decl_ctx.end())
2458 return pos->second;
2459
2460 while (die != NULL)
2461 {
2462 switch (die->Tag())
2463 {
2464 case DW_TAG_namespace:
2465 {
2466 const char *namespace_name = die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL);
2467 if (namespace_name)
2468 {
2469 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2470 assert(type_list);
2471 Declaration decl; // TODO: fill in the decl object
2472 clang::NamespaceDecl *namespace_decl = type_list->GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (cu, die->GetParent()));
2473 if (namespace_decl)
2474 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2475 return namespace_decl;
2476 }
2477 }
2478 break;
2479
2480 default:
2481 break;
2482 }
2483 clang::DeclContext *decl_ctx;
2484 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_specification, DW_INVALID_OFFSET));
2485 if (decl_ctx)
2486 return decl_ctx;
2487
2488 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET));
2489 if (decl_ctx)
2490 return decl_ctx;
2491
2492 die = die->GetParent();
2493 }
2494 return NULL;
2495}
2496
2497TypeSP
2498SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new)
2499{
2500 TypeSP type_sp;
2501
Sean Callanan70a4f922010-08-06 00:32:49 +00002502 AccessType accessibility = eAccessNone;
Chris Lattner24943d22010-06-08 16:52:24 +00002503 if (die != NULL)
2504 {
2505 dw_tag_t tag = die->Tag();
2506 if (die->GetUserData() == NULL)
2507 {
2508 type_is_new = true;
2509
2510 bool is_forward_declaration = false;
2511 DWARFDebugInfoEntry::Attributes attributes;
2512 const char *type_name_cstr = NULL;
2513 ConstString type_name_dbstr;
2514 Type::EncodingUIDType encoding_uid_type = Type::eIsTypeWithUID;
2515 void *clang_type = NULL;
2516
2517 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2518 dw_attr_t attr;
2519
2520 switch (tag)
2521 {
2522 case DW_TAG_base_type:
2523 case DW_TAG_pointer_type:
2524 case DW_TAG_reference_type:
2525 case DW_TAG_typedef:
2526 case DW_TAG_const_type:
2527 case DW_TAG_restrict_type:
2528 case DW_TAG_volatile_type:
2529 {
2530 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2531 // Set a bit that lets us know that we are currently parsing this
2532 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2533
2534 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2535 Declaration decl;
2536 uint32_t encoding = 0;
2537 size_t byte_size = 0;
2538 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
2539
2540 if (num_attributes > 0)
2541 {
2542 uint32_t i;
2543 for (i=0; i<num_attributes; ++i)
2544 {
2545 attr = attributes.AttributeAtIndex(i);
2546 DWARFFormValue form_value;
2547 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2548 {
2549 switch (attr)
2550 {
2551 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2552 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2553 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2554 case DW_AT_name:
2555 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2556 type_name_dbstr.SetCString(type_name_cstr);
2557 break;
2558 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
2559 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
2560 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2561 default:
2562 case DW_AT_sibling:
2563 break;
2564 }
2565 }
2566 }
2567 }
2568
2569 switch (tag)
2570 {
2571 default:
2572 case DW_TAG_base_type:
2573 clang_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, encoding, byte_size * 8);
2574 break;
2575
2576 case DW_TAG_pointer_type:
2577 // The encoding_uid will be embedded into the
2578 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2579 encoding_uid_type = Type::ePointerToTypeWithUID;
2580 break;
2581
2582 case DW_TAG_reference_type:
2583 // The encoding_uid will be embedded into the
2584 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2585 encoding_uid_type = Type::eLValueReferenceToTypeWithUID;
2586 break;
2587
2588 case DW_TAG_typedef:
2589 // The encoding_uid will be embedded into the
2590 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2591 encoding_uid_type = Type::eTypedefToTypeWithUID;
2592 break;
2593
2594 case DW_TAG_const_type:
2595 // The encoding_uid will be embedded into the
2596 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2597 encoding_uid_type = Type::eIsConstTypeWithUID; //ClangASTContext::AddConstModifier (clang_type);
2598 break;
2599
2600 case DW_TAG_restrict_type:
2601 // The encoding_uid will be embedded into the
2602 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2603 encoding_uid_type = Type::eIsRestrictTypeWithUID; //ClangASTContext::AddRestrictModifier (clang_type);
2604 break;
2605
2606 case DW_TAG_volatile_type:
2607 // The encoding_uid will be embedded into the
2608 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2609 encoding_uid_type = Type::eIsVolatileTypeWithUID; //ClangASTContext::AddVolatileModifier (clang_type);
2610 break;
2611 }
2612
Greg Clayton960d6a42010-08-03 00:35:52 +00002613 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
2614 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
2615 {
2616 static ConstString g_objc_type_name_id("id");
2617 static ConstString g_objc_type_name_Class("Class");
2618 static ConstString g_objc_type_name_selector("SEL");
2619
2620 if (type_name_dbstr == g_objc_type_name_id)
2621 {
2622 clang_type = type_list->GetClangASTContext().GetBuiltInType_objc_id();
Greg Clayton960d6a42010-08-03 00:35:52 +00002623 }
2624 else if (type_name_dbstr == g_objc_type_name_Class)
2625 {
2626 clang_type = type_list->GetClangASTContext().GetBuiltInType_objc_Class();
Greg Clayton960d6a42010-08-03 00:35:52 +00002627 }
2628 else if (type_name_dbstr == g_objc_type_name_selector)
2629 {
2630 clang_type = type_list->GetClangASTContext().GetBuiltInType_objc_selector();
Greg Clayton960d6a42010-08-03 00:35:52 +00002631 }
2632 }
2633
Chris Lattner24943d22010-06-08 16:52:24 +00002634 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, encoding_uid_type, &decl, clang_type));
2635
2636 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2637
2638
2639// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
2640// if (encoding_type != NULL)
2641// {
2642// if (encoding_type != DIE_IS_BEING_PARSED)
2643// type_sp->SetEncodingType(encoding_type);
2644// else
2645// m_indirect_fixups.push_back(type_sp.get());
2646// }
2647 }
2648 break;
2649
2650 case DW_TAG_structure_type:
2651 case DW_TAG_union_type:
2652 case DW_TAG_class_type:
2653 {
2654 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2655 // Set a bit that lets us know that we are currently parsing this
2656 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2657
2658 size_t byte_size = 0;
Greg Clayton9488b742010-07-28 02:04:09 +00002659 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner24943d22010-06-08 16:52:24 +00002660 //bool struct_is_class = false;
2661 Declaration decl;
2662 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2663 if (num_attributes > 0)
2664 {
2665 uint32_t i;
2666 for (i=0; i<num_attributes; ++i)
2667 {
2668 attr = attributes.AttributeAtIndex(i);
2669 DWARFFormValue form_value;
2670 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2671 {
2672 switch (attr)
2673 {
Greg Clayton9488b742010-07-28 02:04:09 +00002674 case DW_AT_decl_file:
2675 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
2676 break;
2677
2678 case DW_AT_decl_line:
2679 decl.SetLine(form_value.Unsigned());
2680 break;
2681
2682 case DW_AT_decl_column:
2683 decl.SetColumn(form_value.Unsigned());
2684 break;
2685
Chris Lattner24943d22010-06-08 16:52:24 +00002686 case DW_AT_name:
2687 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2688 type_name_dbstr.SetCString(type_name_cstr);
2689 break;
Greg Clayton9488b742010-07-28 02:04:09 +00002690
2691 case DW_AT_byte_size:
2692 byte_size = form_value.Unsigned();
2693 break;
2694
2695 case DW_AT_accessibility:
2696 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
2697 break;
2698
2699 case DW_AT_declaration:
2700 is_forward_declaration = form_value.Unsigned() != 0;
2701 break;
2702
2703 case DW_AT_APPLE_runtime_class:
2704 class_language = (LanguageType)form_value.Signed();
2705 break;
2706
Chris Lattner24943d22010-06-08 16:52:24 +00002707 case DW_AT_allocated:
2708 case DW_AT_associated:
2709 case DW_AT_data_location:
2710 case DW_AT_description:
2711 case DW_AT_start_scope:
2712 case DW_AT_visibility:
2713 default:
2714 case DW_AT_sibling:
2715 break;
2716 }
2717 }
2718 }
2719 }
2720
2721 int tag_decl_kind = -1;
Sean Callanan70a4f922010-08-06 00:32:49 +00002722 AccessType default_accessibility = eAccessNone;
Chris Lattner24943d22010-06-08 16:52:24 +00002723 if (tag == DW_TAG_structure_type)
2724 {
2725 tag_decl_kind = clang::TTK_Struct;
Sean Callanan70a4f922010-08-06 00:32:49 +00002726 default_accessibility = eAccessPublic;
Chris Lattner24943d22010-06-08 16:52:24 +00002727 }
2728 else if (tag == DW_TAG_union_type)
2729 {
2730 tag_decl_kind = clang::TTK_Union;
Sean Callanan70a4f922010-08-06 00:32:49 +00002731 default_accessibility = eAccessPublic;
Chris Lattner24943d22010-06-08 16:52:24 +00002732 }
2733 else if (tag == DW_TAG_class_type)
2734 {
2735 tag_decl_kind = clang::TTK_Class;
Sean Callanan70a4f922010-08-06 00:32:49 +00002736 default_accessibility = eAccessPrivate;
Chris Lattner24943d22010-06-08 16:52:24 +00002737 }
2738
2739 assert (tag_decl_kind != -1);
Greg Clayton9488b742010-07-28 02:04:09 +00002740 clang_type = type_list->GetClangASTContext().CreateRecordType (type_name_cstr, tag_decl_kind, GetClangDeclContextForDIE (dwarf_cu, die), class_language);
Chris Lattner24943d22010-06-08 16:52:24 +00002741
2742 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
2743 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
2744
2745 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2746
2747// assert(type_sp.get());
2748// if (accessibility)
2749// type_sp->SetAccess(accessibility);
2750//
2751 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
2752 if (die->HasChildren())
2753 {
2754 std::vector<clang::CXXBaseSpecifier *> base_classes;
2755 std::vector<int> member_accessibilities;
2756 bool is_a_class = false;
Greg Clayton9488b742010-07-28 02:04:09 +00002757 ParseChildMembers (sc,
2758 type_sp,
2759 dwarf_cu,
2760 die,
2761 clang_type,
2762 class_language,
2763 base_classes,
2764 member_accessibilities,
2765 default_accessibility,
2766 is_a_class);
2767
Chris Lattner24943d22010-06-08 16:52:24 +00002768 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
2769 // need to tell the clang type it is actually a class.
Greg Clayton9488b742010-07-28 02:04:09 +00002770 if (class_language != eLanguageTypeObjC)
2771 {
2772 if (is_a_class && tag_decl_kind != clang::TTK_Class)
2773 type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class);
2774 }
Chris Lattner24943d22010-06-08 16:52:24 +00002775
2776 // Since DW_TAG_structure_type gets used for both classes
2777 // and structures, we may need to set any DW_TAG_member
2778 // fields to have a "private" access if none was specified.
2779 // When we parsed the child members we tracked that actual
2780 // accessibility value for each DW_TAG_member in the
2781 // "member_accessibilities" array. If the value for the
2782 // member is zero, then it was set to the "default_accessibility"
2783 // which for structs was "public". Below we correct this
2784 // by setting any fields to "private" that weren't correctly
2785 // set.
2786 if (is_a_class && !member_accessibilities.empty())
2787 {
2788 // This is a class and all members that didn't have
2789 // their access specified are private.
Sean Callanan70a4f922010-08-06 00:32:49 +00002790 type_list->GetClangASTContext().SetDefaultAccessForRecordFields (clang_type, eAccessPrivate, &member_accessibilities.front(), member_accessibilities.size());
Chris Lattner24943d22010-06-08 16:52:24 +00002791 }
2792
2793 if (!base_classes.empty())
2794 {
Greg Clayton53d68e72010-07-20 22:52:08 +00002795 type_list->GetClangASTContext().SetBaseClassesForClassType (clang_type, &base_classes.front(), base_classes.size());
2796
2797 // Clang will copy each CXXBaseSpecifier in "base_classes"
2798 // so we have to free them all.
2799 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(), base_classes.size());
Chris Lattner24943d22010-06-08 16:52:24 +00002800 }
Greg Claytone9d0df42010-07-02 01:29:13 +00002801
Chris Lattner24943d22010-06-08 16:52:24 +00002802 }
2803 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
2804 }
2805 break;
2806
2807 case DW_TAG_enumeration_type:
2808 {
2809 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2810 // Set a bit that lets us know that we are currently parsing this
2811 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2812
2813 size_t byte_size = 0;
2814 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
2815 Declaration decl;
2816
2817 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2818 if (num_attributes > 0)
2819 {
2820 uint32_t i;
2821
2822 for (i=0; i<num_attributes; ++i)
2823 {
2824 attr = attributes.AttributeAtIndex(i);
2825 DWARFFormValue form_value;
2826 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2827 {
2828 switch (attr)
2829 {
2830 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2831 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2832 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2833 case DW_AT_name:
2834 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2835 type_name_dbstr.SetCString(type_name_cstr);
2836 break;
2837 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2838 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
Greg Clayton84f80752010-07-22 18:30:50 +00002839 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner24943d22010-06-08 16:52:24 +00002840 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
2841 case DW_AT_allocated:
2842 case DW_AT_associated:
2843 case DW_AT_bit_stride:
2844 case DW_AT_byte_stride:
2845 case DW_AT_data_location:
2846 case DW_AT_description:
2847 case DW_AT_start_scope:
2848 case DW_AT_visibility:
2849 case DW_AT_specification:
2850 case DW_AT_abstract_origin:
2851 case DW_AT_sibling:
2852 break;
2853 }
2854 }
2855 }
2856
2857 clang_type = type_list->GetClangASTContext().CreateEnumerationType(decl, type_name_cstr);
2858 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
2859 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, Type::eIsTypeWithUID, &decl, clang_type));
2860
2861 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2862
2863 if (die->HasChildren())
2864 {
2865 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
2866 void *enumerator_qual_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, DW_ATE_signed, byte_size * 8);
2867 ParseChildEnumerators(sc, type_sp, enumerator_qual_type, byte_size, dwarf_cu, die);
2868 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
2869 }
2870 }
2871 }
2872 break;
2873
Jim Ingham0007dff2010-08-12 01:20:14 +00002874 case DW_TAG_inlined_subroutine:
Chris Lattner24943d22010-06-08 16:52:24 +00002875 case DW_TAG_subprogram:
2876 case DW_TAG_subroutine_type:
2877 {
2878 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2879 // Set a bit that lets us know that we are currently parsing this
2880 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2881
2882 const char *mangled = NULL;
2883 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
2884 Declaration decl;
2885 bool isVariadic = false;
2886 bool is_inline = false;
2887 unsigned type_quals = 0;
2888 clang::FunctionDecl::StorageClass storage = clang::FunctionDecl::None;//, Extern, Static, PrivateExtern
2889
2890
2891 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2892 if (num_attributes > 0)
2893 {
2894 uint32_t i;
2895 for (i=0; i<num_attributes; ++i)
2896 {
2897 attr = attributes.AttributeAtIndex(i);
2898 DWARFFormValue form_value;
2899 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2900 {
2901 switch (attr)
2902 {
2903 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2904 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2905 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2906 case DW_AT_name:
2907 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2908 type_name_dbstr.SetCString(type_name_cstr);
2909 break;
2910
2911 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
2912 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton84f80752010-07-22 18:30:50 +00002913 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner24943d22010-06-08 16:52:24 +00002914 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
2915 case DW_AT_external:
2916 if (form_value.Unsigned())
2917 {
2918 if (storage == clang::FunctionDecl::None)
2919 storage = clang::FunctionDecl::Extern;
2920 else
2921 storage = clang::FunctionDecl::PrivateExtern;
2922 }
2923 break;
2924 case DW_AT_inline:
2925 is_inline = form_value.Unsigned() != 0;
2926 break;
2927
2928 case DW_AT_allocated:
2929 case DW_AT_associated:
2930 case DW_AT_address_class:
2931 case DW_AT_artificial:
2932 case DW_AT_calling_convention:
2933 case DW_AT_data_location:
2934 case DW_AT_elemental:
2935 case DW_AT_entry_pc:
2936 case DW_AT_explicit:
2937 case DW_AT_frame_base:
2938 case DW_AT_high_pc:
2939 case DW_AT_low_pc:
2940 case DW_AT_object_pointer:
2941 case DW_AT_prototyped:
2942 case DW_AT_pure:
2943 case DW_AT_ranges:
2944 case DW_AT_recursive:
2945 case DW_AT_return_addr:
2946 case DW_AT_segment:
2947 case DW_AT_specification:
2948 case DW_AT_start_scope:
2949 case DW_AT_static_link:
2950 case DW_AT_trampoline:
2951 case DW_AT_visibility:
2952 case DW_AT_virtuality:
2953 case DW_AT_vtable_elem_location:
2954 case DW_AT_abstract_origin:
2955 case DW_AT_description:
2956 case DW_AT_sibling:
2957 break;
2958 }
2959 }
2960 }
2961
2962 void *return_clang_type = NULL;
2963 Type *func_type = ResolveTypeUID(type_die_offset);
2964 if (func_type)
2965 return_clang_type = func_type->GetOpaqueClangQualType();
2966 else
Greg Clayton960d6a42010-08-03 00:35:52 +00002967 return_clang_type = type_list->GetClangASTContext().GetBuiltInType_void();
Chris Lattner24943d22010-06-08 16:52:24 +00002968
2969 std::vector<void *> function_param_types;
2970 std::vector<clang::ParmVarDecl*> function_param_decls;
2971
2972 // Parse the function children for the parameters
2973 ParseChildParameters(sc, type_sp, dwarf_cu, die, type_list, function_param_types, function_param_decls);
2974
2975 clang_type = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), isVariadic, type_quals);
2976 if (type_name_cstr)
2977 {
2978 clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline);
2979 // Add the decl to our DIE to decl context map
2980 assert (function_decl);
2981 m_die_to_decl_ctx[die] = function_decl;
2982 if (!function_param_decls.empty())
Greg Clayton53d68e72010-07-20 22:52:08 +00002983 type_list->GetClangASTContext().SetFunctionParameters (function_decl, &function_param_decls.front(), function_param_decls.size());
Chris Lattner24943d22010-06-08 16:52:24 +00002984 }
2985 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, 0, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
2986
2987 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2988 assert(type_sp.get());
2989 }
2990 }
2991 break;
2992
2993 case DW_TAG_array_type:
2994 {
2995 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2996 // Set a bit that lets us know that we are currently parsing this
2997 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2998
2999 size_t byte_size = 0;
3000 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
3001 Declaration decl;
3002 int64_t first_index = 0;
3003 uint32_t byte_stride = 0;
3004 uint32_t bit_stride = 0;
3005 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
3006
3007 if (num_attributes > 0)
3008 {
3009 uint32_t i;
3010 for (i=0; i<num_attributes; ++i)
3011 {
3012 attr = attributes.AttributeAtIndex(i);
3013 DWARFFormValue form_value;
3014 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3015 {
3016 switch (attr)
3017 {
3018 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3019 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3020 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3021 case DW_AT_name:
3022 type_name_cstr = form_value.AsCString(&get_debug_str_data());
3023 type_name_dbstr.SetCString(type_name_cstr);
3024 break;
3025
3026 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
3027 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3028 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3029 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton84f80752010-07-22 18:30:50 +00003030 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner24943d22010-06-08 16:52:24 +00003031 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
3032 case DW_AT_allocated:
3033 case DW_AT_associated:
3034 case DW_AT_data_location:
3035 case DW_AT_description:
3036 case DW_AT_ordering:
3037 case DW_AT_start_scope:
3038 case DW_AT_visibility:
3039 case DW_AT_specification:
3040 case DW_AT_abstract_origin:
3041 case DW_AT_sibling:
3042 break;
3043 }
3044 }
3045 }
3046
3047 Type *element_type = ResolveTypeUID(type_die_offset);
3048
3049 if (element_type)
3050 {
3051 std::vector<uint64_t> element_orders;
3052 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
3053 if (byte_stride == 0 && bit_stride == 0)
3054 byte_stride = element_type->GetByteSize();
3055 void *array_element_type = element_type->GetOpaqueClangQualType();
3056 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3057 uint64_t num_elements = 0;
3058 std::vector<uint64_t>::const_reverse_iterator pos;
3059 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3060 for (pos = element_orders.rbegin(); pos != end; ++pos)
3061 {
3062 num_elements = *pos;
3063 clang_type = type_list->GetClangASTContext().CreateArrayType (array_element_type, num_elements, num_elements * array_element_bit_stride);
3064 array_element_type = clang_type;
3065 array_element_bit_stride = array_element_bit_stride * num_elements;
3066 }
3067 ConstString empty_name;
3068 type_sp.reset( new Type(die->GetOffset(), this, empty_name, array_element_bit_stride / 8, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
3069 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
3070 }
3071 }
3072 }
3073 break;
3074
Greg Claytonfa970692010-06-12 01:20:30 +00003075 case DW_TAG_ptr_to_member_type:
3076 {
3077 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3078 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3079
3080 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
3081
3082 if (num_attributes > 0) {
3083 uint32_t i;
3084 for (i=0; i<num_attributes; ++i)
3085 {
3086 attr = attributes.AttributeAtIndex(i);
3087 DWARFFormValue form_value;
3088 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3089 {
3090 switch (attr)
3091 {
3092 case DW_AT_type:
3093 type_die_offset = form_value.Reference(dwarf_cu); break;
3094 case DW_AT_containing_type:
3095 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3096 }
3097 }
3098 }
3099
3100 Type *pointee_type = ResolveTypeUID(type_die_offset);
3101 Type *class_type = ResolveTypeUID(containing_type_die_offset);
3102
3103 void *pointee_clang_type = pointee_type->GetOpaqueClangQualType();
Greg Claytonf6e509a2010-06-12 15:33:14 +00003104 void *class_clang_type = class_type->GetOpaqueClangQualType();
Greg Claytonfa970692010-06-12 01:20:30 +00003105
Greg Claytonbef15832010-07-14 00:18:15 +00003106 clang_type = type_list->GetClangASTContext().CreateMemberPointerType(pointee_clang_type, class_clang_type);
Greg Claytonfa970692010-06-12 01:20:30 +00003107
Greg Clayton960d6a42010-08-03 00:35:52 +00003108 size_t byte_size = ClangASTType::GetClangTypeBitWidth (type_list->GetClangASTContext().getASTContext(), clang_type) / 8;
Greg Claytonfa970692010-06-12 01:20:30 +00003109
3110 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, NULL, clang_type));
3111 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
3112 }
3113
3114 break;
3115 }
Chris Lattner24943d22010-06-08 16:52:24 +00003116 default:
Greg Claytonfa970692010-06-12 01:20:30 +00003117 assert(false && "Unhandled type tag!");
Chris Lattner24943d22010-06-08 16:52:24 +00003118 break;
3119 }
3120
3121 if (type_sp.get())
3122 {
3123 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3124 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3125
3126 SymbolContextScope * symbol_context_scope = NULL;
3127 if (sc_parent_tag == DW_TAG_compile_unit)
3128 {
3129 symbol_context_scope = sc.comp_unit;
3130 }
3131 else if (sc.function != NULL)
3132 {
3133 symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset());
3134 if (symbol_context_scope == NULL)
3135 symbol_context_scope = sc.function;
3136 }
3137
3138 if (symbol_context_scope != NULL)
3139 {
3140 type_sp->SetSymbolContextScope(symbol_context_scope);
3141 }
3142
3143// if (udt_sp.get())
3144// {
3145// if (is_forward_declaration)
3146// udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
3147// type_sp->SetUserDefinedType(udt_sp);
3148// }
3149
3150 if (type_sp.unique())
3151 {
3152 // We are ready to put this type into the uniqued list up at the module level
3153 TypeSP uniqued_type_sp(m_obj_file->GetModule()->GetTypeList()->InsertUnique(type_sp));
3154
3155 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(uniqued_type_sp.get());
3156
3157 type_sp = uniqued_type_sp;
3158 }
3159 }
3160 }
3161 else
3162 {
3163 switch (tag)
3164 {
3165 case DW_TAG_base_type:
3166 case DW_TAG_pointer_type:
3167 case DW_TAG_reference_type:
3168 case DW_TAG_typedef:
3169 case DW_TAG_const_type:
3170 case DW_TAG_restrict_type:
3171 case DW_TAG_volatile_type:
3172 case DW_TAG_structure_type:
3173 case DW_TAG_union_type:
3174 case DW_TAG_class_type:
3175 case DW_TAG_enumeration_type:
3176 case DW_TAG_subprogram:
3177 case DW_TAG_subroutine_type:
3178 case DW_TAG_array_type:
3179 {
3180 Type *existing_type = (Type*)die->GetUserData();
3181 if (existing_type != DIE_IS_BEING_PARSED)
3182 {
3183 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(existing_type->GetID());
3184 }
3185 }
3186 break;
3187 default:
3188 //assert(!"invalid type tag...");
3189 break;
3190 }
3191 }
3192 }
3193 return type_sp;
3194}
3195
3196size_t
3197SymbolFileDWARF::ParseTypes (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children)
3198{
3199 size_t types_added = 0;
3200 while (die != NULL)
3201 {
3202 bool type_is_new = false;
3203 if (ParseType(sc, dwarf_cu, die, type_is_new).get())
3204 {
3205 if (type_is_new)
3206 ++types_added;
3207 }
3208
3209 if (parse_children && die->HasChildren())
3210 {
3211 if (die->Tag() == DW_TAG_subprogram)
3212 {
3213 SymbolContext child_sc(sc);
3214 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3215 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3216 }
3217 else
3218 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3219 }
3220
3221 if (parse_siblings)
3222 die = die->GetSibling();
3223 else
3224 die = NULL;
3225 }
3226 return types_added;
3227}
3228
3229
3230size_t
3231SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3232{
3233 assert(sc.comp_unit && sc.function);
3234 size_t functions_added = 0;
3235 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3236 if (dwarf_cu)
3237 {
3238 dw_offset_t function_die_offset = sc.function->GetID();
3239 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3240 if (function_die)
3241 {
3242 ParseFunctionBlocks(sc, Block::RootID, dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
3243 }
3244 }
3245
3246 return functions_added;
3247}
3248
3249
3250size_t
3251SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3252{
3253 // At least a compile unit must be valid
3254 assert(sc.comp_unit);
3255 size_t types_added = 0;
3256 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3257 if (dwarf_cu)
3258 {
3259 if (sc.function)
3260 {
3261 dw_offset_t function_die_offset = sc.function->GetID();
3262 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3263 if (func_die && func_die->HasChildren())
3264 {
3265 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3266 }
3267 }
3268 else
3269 {
3270 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3271 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3272 {
3273 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3274 }
3275 }
3276 }
3277
3278 return types_added;
3279}
3280
3281size_t
3282SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3283{
3284 if (sc.comp_unit != NULL)
3285 {
3286 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3287
3288 if (dwarf_cu == NULL)
3289 return 0;
3290
3291 if (sc.function)
3292 {
3293 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
3294 return ParseVariables(sc, dwarf_cu, function_die->GetFirstChild(), true, true);
3295 }
3296 else if (sc.comp_unit)
3297 {
3298 uint32_t vars_added = 0;
3299 VariableListSP variables (sc.comp_unit->GetVariableList(false));
3300
3301 if (variables.get() == NULL)
3302 {
3303 variables.reset(new VariableList());
3304 sc.comp_unit->SetVariableList(variables);
3305
3306 // Index if we already haven't to make sure the compile units
3307 // get indexed and make their global DIE index list
3308 if (!m_indexed)
3309 Index ();
3310
3311 const size_t num_globals = dwarf_cu->GetNumGlobals();
3312 for (size_t idx=0; idx<num_globals; ++idx)
3313 {
3314 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetGlobalDIEAtIndex (idx)));
3315 if (var_sp)
3316 {
3317 variables->AddVariable(var_sp);
3318 ++vars_added;
3319 }
3320 }
3321 }
3322 return vars_added;
3323 }
3324 }
3325 return 0;
3326}
3327
3328
3329VariableSP
3330SymbolFileDWARF::ParseVariableDIE
3331(
3332 const SymbolContext& sc,
3333 const DWARFCompileUnit* dwarf_cu,
3334 const DWARFDebugInfoEntry *die
3335)
3336{
3337
3338 VariableSP var_sp;
3339
3340 const dw_tag_t tag = die->Tag();
3341 DWARFDebugInfoEntry::Attributes attributes;
3342 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
3343 if (num_attributes > 0)
3344 {
3345 const char *name = NULL;
3346 Declaration decl;
3347 uint32_t i;
3348 TypeSP type_sp;
3349 Type *var_type = NULL;
3350 DWARFExpression location;
3351 bool is_external = false;
3352 bool is_artificial = false;
Sean Callanan70a4f922010-08-06 00:32:49 +00003353 AccessType accessibility = eAccessNone;
Chris Lattner24943d22010-06-08 16:52:24 +00003354
3355 for (i=0; i<num_attributes; ++i)
3356 {
3357 dw_attr_t attr = attributes.AttributeAtIndex(i);
3358 DWARFFormValue form_value;
3359 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3360 {
3361 switch (attr)
3362 {
3363 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3364 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3365 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3366 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
3367 case DW_AT_type: var_type = GetUniquedTypeForDIEOffset(form_value.Reference(dwarf_cu), type_sp, 0, 0, false); break;
3368 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
3369 case DW_AT_location:
3370 {
3371 if (form_value.BlockData())
3372 {
3373 const DataExtractor& debug_info_data = get_debug_info_data();
3374
3375 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3376 uint32_t block_length = form_value.Unsigned();
3377 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length, NULL);
3378 }
3379 else
3380 {
3381 const DataExtractor& debug_loc_data = get_debug_loc_data();
3382 const dw_offset_t debug_loc_offset = form_value.Unsigned();
3383
3384 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
3385 if (loc_list_length > 0)
3386 {
3387 Address base_address(dwarf_cu->GetBaseAddress(), m_obj_file->GetSectionList());
3388 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length, &base_address);
3389 }
3390 }
3391 }
3392 break;
3393
3394 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Greg Clayton84f80752010-07-22 18:30:50 +00003395 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner24943d22010-06-08 16:52:24 +00003396 case DW_AT_const_value:
3397 case DW_AT_declaration:
3398 case DW_AT_description:
3399 case DW_AT_endianity:
3400 case DW_AT_segment:
3401 case DW_AT_start_scope:
3402 case DW_AT_visibility:
3403 default:
3404 case DW_AT_abstract_origin:
3405 case DW_AT_sibling:
3406 case DW_AT_specification:
3407 break;
3408 }
3409 }
3410 }
3411
3412 if (location.IsValid())
3413 {
3414 assert(var_type != DIE_IS_BEING_PARSED);
3415
3416 ConstString var_name(name);
3417
3418 ValueType scope = eValueTypeInvalid;
3419
3420 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3421 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3422
3423 if (tag == DW_TAG_formal_parameter)
3424 scope = eValueTypeVariableArgument;
3425 else if (is_external || parent_tag == DW_TAG_compile_unit)
3426 scope = eValueTypeVariableGlobal;
3427 else
3428 scope = eValueTypeVariableLocal;
3429
3430 SymbolContextScope * symbol_context_scope = NULL;
3431 if (parent_tag == DW_TAG_compile_unit)
3432 {
3433 symbol_context_scope = sc.comp_unit;
3434 }
3435 else if (sc.function != NULL)
3436 {
3437 symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset());
3438 if (symbol_context_scope == NULL)
3439 symbol_context_scope = sc.function;
3440 }
3441
3442 assert(symbol_context_scope != NULL);
3443 var_sp.reset (new Variable(die->GetOffset(),
3444 var_name,
3445 var_type,
3446 scope,
3447 symbol_context_scope,
3448 &decl,
3449 location,
3450 is_external,
3451 is_artificial));
3452 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(var_sp.get());
3453 }
3454 }
3455 return var_sp;
3456}
3457
3458size_t
3459SymbolFileDWARF::ParseVariables
3460(
3461 const SymbolContext& sc,
3462 const DWARFCompileUnit* dwarf_cu,
3463 const DWARFDebugInfoEntry *orig_die,
3464 bool parse_siblings,
3465 bool parse_children,
3466 VariableList* cc_variable_list
3467)
3468{
3469 if (orig_die == NULL)
3470 return 0;
3471
3472 size_t vars_added = 0;
3473 const DWARFDebugInfoEntry *die = orig_die;
3474 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
3475 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3476 VariableListSP variables;
3477 switch (parent_tag)
3478 {
3479 case DW_TAG_compile_unit:
3480 if (sc.comp_unit != NULL)
3481 {
3482 variables = sc.comp_unit->GetVariableList(false);
3483 if (variables.get() == NULL)
3484 {
3485 variables.reset(new VariableList());
3486 sc.comp_unit->SetVariableList(variables);
3487 }
3488 }
3489 else
3490 {
3491 assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
3492 vars_added = 0;
3493 }
3494 break;
3495
3496 case DW_TAG_subprogram:
3497 case DW_TAG_inlined_subroutine:
3498 case DW_TAG_lexical_block:
3499 if (sc.function != NULL)
3500 {
3501 // Check to see if we already have parsed the variables for the given scope
3502 variables = sc.function->GetBlocks(true).GetVariableList(sc_parent_die->GetOffset(), false, false);
3503 if (variables.get() == NULL)
3504 {
3505 variables.reset(new VariableList());
3506 sc.function->GetBlocks(true).SetVariableList(sc_parent_die->GetOffset(), variables);
3507 }
3508 }
3509 else
3510 {
3511 assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
3512 vars_added = 0;
3513 }
3514 break;
3515
3516 default:
3517 assert(!"Didn't find appropriate parent DIE for variable list...");
3518 break;
3519 }
3520
3521 // We need to have a variable list at this point that we can add variables to
3522 assert(variables.get());
3523
3524 while (die != NULL)
3525 {
3526 dw_tag_t tag = die->Tag();
3527
3528 // Check to see if we have already parsed this variable or constant?
3529 if (die->GetUserData() == NULL)
3530 {
3531 // We haven't already parsed it, lets do that now.
3532 if ((tag == DW_TAG_variable) ||
3533 (tag == DW_TAG_constant) ||
3534 (tag == DW_TAG_formal_parameter && sc.function))
3535 {
3536 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die));
3537 if (var_sp)
3538 {
3539 variables->AddVariable(var_sp);
3540 ++vars_added;
3541 }
3542 }
3543 }
3544
3545 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
3546
3547 if (!skip_children && parse_children && die->HasChildren())
3548 {
3549 vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), true, true);
3550 //vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), parse_siblings, parse_children);
3551 }
3552
3553 if (parse_siblings)
3554 die = die->GetSibling();
3555 else
3556 die = NULL;
3557 }
3558
3559 if (cc_variable_list)
3560 {
3561 cc_variable_list->AddVariables(variables.get());
3562 }
3563
3564 return vars_added;
3565}
3566
3567//------------------------------------------------------------------
3568// PluginInterface protocol
3569//------------------------------------------------------------------
3570const char *
3571SymbolFileDWARF::GetPluginName()
3572{
3573 return "SymbolFileDWARF";
3574}
3575
3576const char *
3577SymbolFileDWARF::GetShortPluginName()
3578{
3579 return GetPluginNameStatic();
3580}
3581
3582uint32_t
3583SymbolFileDWARF::GetPluginVersion()
3584{
3585 return 1;
3586}
3587
3588void
3589SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
3590{
3591}
3592
3593Error
3594SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
3595{
3596 Error error;
3597 error.SetErrorString("No plug-in command are currently supported.");
3598 return error;
3599}
3600
3601Log *
3602SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
3603{
3604 return NULL;
3605}
3606