blob: f7a177dc533f2644c9ec358e692cb89394984a58 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- SymbolFileDWARF.cpp ------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "SymbolFileDWARF.h"
11
12// Other libraries and framework includes
13#include "clang/AST/ASTConsumer.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclGroup.h"
17#include "clang/Basic/Builtins.h"
18#include "clang/Basic/IdentifierTable.h"
19#include "clang/Basic/LangOptions.h"
20#include "clang/Basic/SourceManager.h"
21#include "clang/Basic/TargetInfo.h"
22#include "clang/Basic/Specifiers.h"
23
24#include "lldb/Core/Module.h"
25#include "lldb/Core/PluginManager.h"
26#include "lldb/Core/RegularExpression.h"
27#include "lldb/Core/Scalar.h"
28#include "lldb/Core/Section.h"
Greg Claytonc685f8e2010-09-15 04:15:46 +000029#include "lldb/Core/StreamFile.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Core/Timer.h"
31#include "lldb/Core/Value.h"
32
33#include "lldb/Symbol/Block.h"
34#include "lldb/Symbol/CompileUnit.h"
35#include "lldb/Symbol/LineTable.h"
36#include "lldb/Symbol/ObjectFile.h"
37#include "lldb/Symbol/SymbolVendor.h"
38#include "lldb/Symbol/VariableList.h"
39
40#include "DWARFCompileUnit.h"
41#include "DWARFDebugAbbrev.h"
42#include "DWARFDebugAranges.h"
43#include "DWARFDebugInfo.h"
44#include "DWARFDebugInfoEntry.h"
45#include "DWARFDebugLine.h"
46#include "DWARFDebugPubnames.h"
47#include "DWARFDebugRanges.h"
48#include "DWARFDIECollection.h"
49#include "DWARFFormValue.h"
50#include "DWARFLocationList.h"
51#include "LogChannelDWARF.h"
52
53#include <map>
54
Greg Clayton594e5ed2010-09-27 21:07:38 +000055#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056
57using namespace lldb;
58using namespace lldb_private;
59
60
Sean Callananc7fbf732010-08-06 00:32:49 +000061static AccessType
Greg Clayton8cf05932010-07-22 18:30:50 +000062DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063{
64 switch (dwarf_accessibility)
65 {
Sean Callananc7fbf732010-08-06 00:32:49 +000066 case DW_ACCESS_public: return eAccessPublic;
67 case DW_ACCESS_private: return eAccessPrivate;
68 case DW_ACCESS_protected: return eAccessProtected;
Greg Clayton8cf05932010-07-22 18:30:50 +000069 default: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000070 }
Sean Callananc7fbf732010-08-06 00:32:49 +000071 return eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000072}
73
74void
75SymbolFileDWARF::Initialize()
76{
77 LogChannelDWARF::Initialize();
78 PluginManager::RegisterPlugin (GetPluginNameStatic(),
79 GetPluginDescriptionStatic(),
80 CreateInstance);
81}
82
83void
84SymbolFileDWARF::Terminate()
85{
86 PluginManager::UnregisterPlugin (CreateInstance);
87 LogChannelDWARF::Initialize();
88}
89
90
91const char *
92SymbolFileDWARF::GetPluginNameStatic()
93{
94 return "symbol-file.dwarf2";
95}
96
97const char *
98SymbolFileDWARF::GetPluginDescriptionStatic()
99{
100 return "DWARF and DWARF3 debug symbol file reader.";
101}
102
103
104SymbolFile*
105SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
106{
107 return new SymbolFileDWARF(obj_file);
108}
109
110//----------------------------------------------------------------------
111// Gets the first parent that is a lexical block, function or inlined
112// subroutine, or compile unit.
113//----------------------------------------------------------------------
114static const DWARFDebugInfoEntry *
115GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
116{
117 const DWARFDebugInfoEntry *die;
118 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
119 {
120 dw_tag_t tag = die->Tag();
121
122 switch (tag)
123 {
124 case DW_TAG_compile_unit:
125 case DW_TAG_subprogram:
126 case DW_TAG_inlined_subroutine:
127 case DW_TAG_lexical_block:
128 return die;
129 }
130 }
131 return NULL;
132}
133
134
135SymbolFileDWARF::SymbolFileDWARF(ObjectFile* ofile) :
136 SymbolFile(ofile),
137 m_flags(),
138 m_data_debug_abbrev(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139 m_data_debug_frame(),
140 m_data_debug_info(),
141 m_data_debug_line(),
142 m_data_debug_loc(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000143 m_data_debug_ranges(),
144 m_data_debug_str(),
145 m_abbr(),
146 m_aranges(),
147 m_info(),
148 m_line(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000149 m_function_basename_index(),
150 m_function_fullname_index(),
151 m_function_method_index(),
152 m_function_selector_index(),
153 m_global_index(),
154 m_types_index(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000155 m_indexed(false),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000156 m_ranges()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000157{
158}
159
160SymbolFileDWARF::~SymbolFileDWARF()
161{
162}
163
164bool
165SymbolFileDWARF::SupportedVersion(uint16_t version)
166{
167 return version == 2 || version == 3;
168}
169
170uint32_t
171SymbolFileDWARF::GetAbilities ()
172{
173 uint32_t abilities = 0;
174 if (m_obj_file != NULL)
175 {
176 const Section* section = NULL;
177 const SectionList *section_list = m_obj_file->GetSectionList();
178 if (section_list == NULL)
179 return 0;
180
181 uint64_t debug_abbrev_file_size = 0;
182 uint64_t debug_aranges_file_size = 0;
183 uint64_t debug_frame_file_size = 0;
184 uint64_t debug_info_file_size = 0;
185 uint64_t debug_line_file_size = 0;
186 uint64_t debug_loc_file_size = 0;
187 uint64_t debug_macinfo_file_size = 0;
188 uint64_t debug_pubnames_file_size = 0;
189 uint64_t debug_pubtypes_file_size = 0;
190 uint64_t debug_ranges_file_size = 0;
191 uint64_t debug_str_file_size = 0;
192
193 static ConstString g_dwarf_section_name ("__DWARF");
194
195 section = section_list->FindSectionByName(g_dwarf_section_name).get();
196
197 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000198 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000199 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
Greg Clayton4ceb9982010-07-21 22:54:26 +0000200 section_list = &section->GetChildren ();
201 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000202
Greg Clayton4ceb9982010-07-21 22:54:26 +0000203 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204 if (section != NULL)
205 {
206 debug_info_file_size = section->GetByteSize();
207
Greg Clayton4ceb9982010-07-21 22:54:26 +0000208 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000209 if (section)
210 debug_abbrev_file_size = section->GetByteSize();
211 else
212 m_flags.Set (flagsGotDebugAbbrevData);
213
Greg Clayton4ceb9982010-07-21 22:54:26 +0000214 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215 if (section)
216 debug_aranges_file_size = section->GetByteSize();
217 else
218 m_flags.Set (flagsGotDebugArangesData);
219
Greg Clayton4ceb9982010-07-21 22:54:26 +0000220 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000221 if (section)
222 debug_frame_file_size = section->GetByteSize();
223 else
224 m_flags.Set (flagsGotDebugFrameData);
225
Greg Clayton4ceb9982010-07-21 22:54:26 +0000226 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000227 if (section)
228 debug_line_file_size = section->GetByteSize();
229 else
230 m_flags.Set (flagsGotDebugLineData);
231
Greg Clayton4ceb9982010-07-21 22:54:26 +0000232 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000233 if (section)
234 debug_loc_file_size = section->GetByteSize();
235 else
236 m_flags.Set (flagsGotDebugLocData);
237
Greg Clayton4ceb9982010-07-21 22:54:26 +0000238 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000239 if (section)
240 debug_macinfo_file_size = section->GetByteSize();
241 else
242 m_flags.Set (flagsGotDebugMacInfoData);
243
Greg Clayton4ceb9982010-07-21 22:54:26 +0000244 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245 if (section)
246 debug_pubnames_file_size = section->GetByteSize();
247 else
248 m_flags.Set (flagsGotDebugPubNamesData);
249
Greg Clayton4ceb9982010-07-21 22:54:26 +0000250 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000251 if (section)
252 debug_pubtypes_file_size = section->GetByteSize();
253 else
254 m_flags.Set (flagsGotDebugPubTypesData);
255
Greg Clayton4ceb9982010-07-21 22:54:26 +0000256 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000257 if (section)
258 debug_ranges_file_size = section->GetByteSize();
259 else
260 m_flags.Set (flagsGotDebugRangesData);
261
Greg Clayton4ceb9982010-07-21 22:54:26 +0000262 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263 if (section)
264 debug_str_file_size = section->GetByteSize();
265 else
266 m_flags.Set (flagsGotDebugStrData);
267 }
268
269 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
270 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
271
272 if (debug_line_file_size > 0)
273 abilities |= LineTables;
274
275 if (debug_aranges_file_size > 0)
276 abilities |= AddressAcceleratorTable;
277
278 if (debug_pubnames_file_size > 0)
279 abilities |= FunctionAcceleratorTable;
280
281 if (debug_pubtypes_file_size > 0)
282 abilities |= TypeAcceleratorTable;
283
284 if (debug_macinfo_file_size > 0)
285 abilities |= MacroInformation;
286
287 if (debug_frame_file_size > 0)
288 abilities |= CallFrameInformation;
289 }
290 return abilities;
291}
292
293const DataExtractor&
Greg Clayton4ceb9982010-07-21 22:54:26 +0000294SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000295{
296 if (m_flags.IsClear (got_flag))
297 {
298 m_flags.Set (got_flag);
299 const SectionList *section_list = m_obj_file->GetSectionList();
300 if (section_list)
301 {
Greg Clayton4ceb9982010-07-21 22:54:26 +0000302 Section *section = section_list->FindSectionByType(sect_type, true).get();
303 if (section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000304 {
305 // See if we memory mapped the DWARF segment?
306 if (m_dwarf_data.GetByteSize())
307 {
308 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
309 }
310 else
311 {
312 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
313 data.Clear();
314 }
315 }
316 }
317 }
318 return data;
319}
320
321const DataExtractor&
322SymbolFileDWARF::get_debug_abbrev_data()
323{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000324 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325}
326
327const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328SymbolFileDWARF::get_debug_frame_data()
329{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000330 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331}
332
333const DataExtractor&
334SymbolFileDWARF::get_debug_info_data()
335{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000336 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337}
338
339const DataExtractor&
340SymbolFileDWARF::get_debug_line_data()
341{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000342 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343}
344
345const DataExtractor&
346SymbolFileDWARF::get_debug_loc_data()
347{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000348 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349}
350
351const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000352SymbolFileDWARF::get_debug_ranges_data()
353{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000354 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000355}
356
357const DataExtractor&
358SymbolFileDWARF::get_debug_str_data()
359{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000360 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361}
362
363
364DWARFDebugAbbrev*
365SymbolFileDWARF::DebugAbbrev()
366{
367 if (m_abbr.get() == NULL)
368 {
369 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
370 if (debug_abbrev_data.GetByteSize() > 0)
371 {
372 m_abbr.reset(new DWARFDebugAbbrev());
373 if (m_abbr.get())
374 m_abbr->Parse(debug_abbrev_data);
375 }
376 }
377 return m_abbr.get();
378}
379
380const DWARFDebugAbbrev*
381SymbolFileDWARF::DebugAbbrev() const
382{
383 return m_abbr.get();
384}
385
386DWARFDebugAranges*
387SymbolFileDWARF::DebugAranges()
388{
Greg Clayton016a95e2010-09-14 02:20:48 +0000389 // It turns out that llvm-gcc doesn't generate .debug_aranges in .o files
390 // and we are already parsing all of the DWARF because the .debug_pubnames
391 // is useless (it only mentions symbols that are externally visible), so
392 // don't use the .debug_aranges section, we should be using a debug aranges
393 // we got from SymbolFileDWARF::Index().
394
395 if (!m_indexed)
396 Index();
397
398
399// if (m_aranges.get() == NULL)
400// {
401// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
402// m_aranges.reset(new DWARFDebugAranges());
403// if (m_aranges.get())
404// {
405// const DataExtractor &debug_aranges_data = get_debug_aranges_data();
406// if (debug_aranges_data.GetByteSize() > 0)
407// m_aranges->Extract(debug_aranges_data);
408// else
409// m_aranges->Generate(this);
410// }
411// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000412 return m_aranges.get();
413}
414
415const DWARFDebugAranges*
416SymbolFileDWARF::DebugAranges() const
417{
418 return m_aranges.get();
419}
420
421
422DWARFDebugInfo*
423SymbolFileDWARF::DebugInfo()
424{
425 if (m_info.get() == NULL)
426 {
427 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
428 if (get_debug_info_data().GetByteSize() > 0)
429 {
430 m_info.reset(new DWARFDebugInfo());
431 if (m_info.get())
432 {
433 m_info->SetDwarfData(this);
434 }
435 }
436 }
437 return m_info.get();
438}
439
440const DWARFDebugInfo*
441SymbolFileDWARF::DebugInfo() const
442{
443 return m_info.get();
444}
445
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446DWARFCompileUnit*
447SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
448{
449 DWARFDebugInfo* info = DebugInfo();
450 if (info)
451 return info->GetCompileUnit(cu_uid).get();
452 return NULL;
453}
454
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000455
456DWARFDebugRanges*
457SymbolFileDWARF::DebugRanges()
458{
459 if (m_ranges.get() == NULL)
460 {
461 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
462 if (get_debug_ranges_data().GetByteSize() > 0)
463 {
464 m_ranges.reset(new DWARFDebugRanges());
465 if (m_ranges.get())
466 m_ranges->Extract(this);
467 }
468 }
469 return m_ranges.get();
470}
471
472const DWARFDebugRanges*
473SymbolFileDWARF::DebugRanges() const
474{
475 return m_ranges.get();
476}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000477
478bool
Greg Clayton0fffff52010-09-24 05:15:53 +0000479SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000480{
481 if (cu != NULL)
482 {
483 const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly ();
484 if (cu_die)
485 {
486 const char * cu_die_name = cu_die->GetName(this, cu);
487 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL);
Greg Clayton9e409562010-07-28 02:04:09 +0000488 LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_language, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489 if (cu_die_name)
490 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000491 FileSpec cu_file_spec;
492
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000493 if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0])
494 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000495 // If we have a full path to the compile unit, we don't need to resolve
496 // the file. This can be expensive e.g. when the source files are NFS mounted.
497 cu_file_spec.SetFile (cu_die_name, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000498 }
499 else
500 {
501 std::string fullpath(cu_comp_dir);
502 if (*fullpath.rbegin() != '/')
503 fullpath += '/';
504 fullpath += cu_die_name;
Jim Ingham0909e5f2010-09-16 00:57:33 +0000505 cu_file_spec.SetFile (fullpath.c_str(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000506 }
507
Jim Ingham0909e5f2010-09-16 00:57:33 +0000508 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, cu_file_spec, cu->GetOffset(), class_language));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000509 if (compile_unit_sp.get())
510 {
511 cu->SetUserData(compile_unit_sp.get());
512 return true;
513 }
514 }
515 }
516 }
517 return false;
518}
519
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000520uint32_t
521SymbolFileDWARF::GetNumCompileUnits()
522{
523 DWARFDebugInfo* info = DebugInfo();
524 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000525 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000526 return 0;
527}
528
529CompUnitSP
530SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
531{
532 CompUnitSP comp_unit;
533 DWARFDebugInfo* info = DebugInfo();
534 if (info)
535 {
536 DWARFCompileUnit* cu = info->GetCompileUnitAtIndex(cu_idx);
537 if (cu != NULL)
538 {
539 // Our symbol vendor shouldn't be asking us to add a compile unit that
540 // has already been added to it, which this DWARF plug-in knows as it
541 // stores the lldb compile unit (CompileUnit) pointer in each
542 // DWARFCompileUnit object when it gets added.
543 assert(cu->GetUserData() == NULL);
544 ParseCompileUnit(cu, comp_unit);
545 }
546 }
547 return comp_unit;
548}
549
550static void
551AddRangesToBlock
552(
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000553 Block& block,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000554 DWARFDebugRanges::RangeList& ranges,
555 addr_t block_base_addr
556)
557{
558 ranges.SubtractOffset (block_base_addr);
559 size_t range_idx = 0;
560 const DWARFDebugRanges::Range *debug_range;
561 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
562 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000563 block.AddRange(debug_range->begin_offset, debug_range->end_offset);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000564 }
565}
566
567
568Function *
Greg Clayton0fffff52010-09-24 05:15:53 +0000569SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000570{
571 DWARFDebugRanges::RangeList func_ranges;
572 const char *name = NULL;
573 const char *mangled = NULL;
574 int decl_file = 0;
575 int decl_line = 0;
576 int decl_column = 0;
577 int call_file = 0;
578 int call_line = 0;
579 int call_column = 0;
580 DWARFExpression frame_base;
581
582 // Parse the function prototype as a type that can then be added to concrete function instance
583 ParseTypes (sc, dwarf_cu, die, false, false);
584 //FixupTypes();
585
586 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
587 {
588 // Union of all ranges in the function DIE (if the function is discontiguous)
589 AddressRange func_range;
590 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
591 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
592 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
593 {
594 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
595 if (func_range.GetBaseAddress().IsValid())
596 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
597 }
598
599 if (func_range.GetBaseAddress().IsValid())
600 {
601 Mangled func_name;
602 if (mangled)
603 func_name.SetValue(mangled, true);
604 else if (name)
605 func_name.SetValue(name, false);
606
607 FunctionSP func_sp;
608 std::auto_ptr<Declaration> decl_ap;
609 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
610 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column));
611
Greg Clayton594e5ed2010-09-27 21:07:38 +0000612 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000613
614 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
615
616 func_range.GetBaseAddress().ResolveLinkedAddress();
617
618 func_sp.reset(new Function (sc.comp_unit,
619 die->GetOffset(), // UserID is the DIE offset
620 die->GetOffset(),
621 func_name,
622 func_type,
623 func_range)); // first address range
624
625 if (func_sp.get() != NULL)
626 {
627 func_sp->GetFrameBaseExpression() = frame_base;
628 sc.comp_unit->AddFunction(func_sp);
629 return func_sp.get();
630 }
631 }
632 }
633 return NULL;
634}
635
636size_t
637SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
638{
639 assert (sc.comp_unit);
640 size_t functions_added = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +0000641 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000642 if (dwarf_cu)
643 {
644 DWARFDIECollection function_dies;
645 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
646 size_t func_idx;
647 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
648 {
649 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
650 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
651 {
652 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
653 ++functions_added;
654 }
655 }
656 //FixupTypes();
657 }
658 return functions_added;
659}
660
661bool
662SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
663{
664 assert (sc.comp_unit);
665 DWARFCompileUnit* cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
666 assert (cu);
667 const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly();
668
669 if (cu_die)
670 {
671 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL);
672 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
673
674 // All file indexes in DWARF are one based and a file of index zero is
675 // supposed to be the compile unit itself.
676 support_files.Append (*sc.comp_unit);
677
678 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
679 }
680 return false;
681}
682
683struct ParseDWARFLineTableCallbackInfo
684{
685 LineTable* line_table;
686 const SectionList *section_list;
687 lldb::addr_t prev_sect_file_base_addr;
688 lldb::addr_t curr_sect_file_base_addr;
689 bool is_oso_for_debug_map;
690 bool prev_in_final_executable;
691 DWARFDebugLine::Row prev_row;
692 SectionSP prev_section_sp;
693 SectionSP curr_section_sp;
694};
695
696//----------------------------------------------------------------------
697// ParseStatementTableCallback
698//----------------------------------------------------------------------
699static void
700ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
701{
702 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
703 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
704 {
705 // Just started parsing the line table
706 }
707 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
708 {
709 // Done parsing line table, nothing to do for the cleanup
710 }
711 else
712 {
713 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
714 // We have a new row, lets append it
715
716 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
717 {
718 info->prev_section_sp = info->curr_section_sp;
719 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
720 // If this is an end sequence entry, then we subtract one from the
721 // address to make sure we get an address that is not the end of
722 // a section.
723 if (state.end_sequence && state.address != 0)
724 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
725 else
726 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
727
728 if (info->curr_section_sp.get())
729 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
730 else
731 info->curr_sect_file_base_addr = 0;
732 }
733 if (info->curr_section_sp.get())
734 {
735 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
736 // Check for the fancy section magic to determine if we
737
738 if (info->is_oso_for_debug_map)
739 {
740 // When this is a debug map object file that contains DWARF
741 // (referenced from an N_OSO debug map nlist entry) we will have
742 // a file address in the file range for our section from the
743 // original .o file, and a load address in the executable that
744 // contains the debug map.
745 //
746 // If the sections for the file range and load range are
747 // different, we have a remapped section for the function and
748 // this address is resolved. If they are the same, then the
749 // function for this address didn't make it into the final
750 // executable.
751 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
752
753 // If we are doing DWARF with debug map, then we need to carefully
754 // add each line table entry as there may be gaps as functions
755 // get moved around or removed.
756 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
757 {
758 if (info->prev_in_final_executable)
759 {
760 bool terminate_previous_entry = false;
761 if (!curr_in_final_executable)
762 {
763 // Check for the case where the previous line entry
764 // in a function made it into the final executable,
765 // yet the current line entry falls in a function
766 // that didn't. The line table used to be contiguous
767 // through this address range but now it isn't. We
768 // need to terminate the previous line entry so
769 // that we can reconstruct the line range correctly
770 // for it and to keep the line table correct.
771 terminate_previous_entry = true;
772 }
773 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
774 {
775 // Check for cases where the line entries used to be
776 // contiguous address ranges, but now they aren't.
777 // This can happen when order files specify the
778 // ordering of the functions.
779 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
780 Section *curr_sect = info->curr_section_sp.get();
781 Section *prev_sect = info->prev_section_sp.get();
782 assert (curr_sect->GetLinkedSection());
783 assert (prev_sect->GetLinkedSection());
784 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
785 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
786 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
787 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
788 if (object_file_addr_delta != linked_file_addr_delta)
789 terminate_previous_entry = true;
790 }
791
792 if (terminate_previous_entry)
793 {
794 line_table->InsertLineEntry (info->prev_section_sp,
795 state.address - info->prev_sect_file_base_addr,
796 info->prev_row.line,
797 info->prev_row.column,
798 info->prev_row.file,
799 false, // is_stmt
800 false, // basic_block
801 false, // state.prologue_end
802 false, // state.epilogue_begin
803 true); // end_sequence);
804 }
805 }
806 }
807
808 if (curr_in_final_executable)
809 {
810 line_table->InsertLineEntry (info->curr_section_sp,
811 curr_line_section_offset,
812 state.line,
813 state.column,
814 state.file,
815 state.is_stmt,
816 state.basic_block,
817 state.prologue_end,
818 state.epilogue_begin,
819 state.end_sequence);
820 info->prev_section_sp = info->curr_section_sp;
821 }
822 else
823 {
824 // If the current address didn't make it into the final
825 // executable, the current section will be the __text
826 // segment in the .o file, so we need to clear this so
827 // we can catch the next function that did make it into
828 // the final executable.
829 info->prev_section_sp.reset();
830 info->curr_section_sp.reset();
831 }
832
833 info->prev_in_final_executable = curr_in_final_executable;
834 }
835 else
836 {
837 // We are not in an object file that contains DWARF for an
838 // N_OSO, this is just a normal DWARF file. The DWARF spec
839 // guarantees that the addresses will be in increasing order
840 // so, since we store line tables in file address order, we
841 // can always just append the line entry without needing to
842 // search for the correct insertion point (we don't need to
843 // use LineEntry::InsertLineEntry()).
844 line_table->AppendLineEntry (info->curr_section_sp,
845 curr_line_section_offset,
846 state.line,
847 state.column,
848 state.file,
849 state.is_stmt,
850 state.basic_block,
851 state.prologue_end,
852 state.epilogue_begin,
853 state.end_sequence);
854 }
855 }
856
857 info->prev_row = state;
858 }
859}
860
861bool
862SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
863{
864 assert (sc.comp_unit);
865 if (sc.comp_unit->GetLineTable() != NULL)
866 return true;
867
868 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
869 if (dwarf_cu)
870 {
871 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
872 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
873 if (cu_line_offset != DW_INVALID_OFFSET)
874 {
875 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
876 if (line_table_ap.get())
877 {
878 ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_flags.IsSet (flagsDWARFIsOSOForDebugMap), false};
879 uint32_t offset = cu_line_offset;
880 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
881 sc.comp_unit->SetLineTable(line_table_ap.release());
882 return true;
883 }
884 }
885 }
886 return false;
887}
888
889size_t
890SymbolFileDWARF::ParseFunctionBlocks
891(
892 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000893 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +0000894 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000895 const DWARFDebugInfoEntry *die,
896 addr_t subprogram_low_pc,
897 bool parse_siblings,
898 bool parse_children
899)
900{
901 size_t blocks_added = 0;
902 while (die != NULL)
903 {
904 dw_tag_t tag = die->Tag();
905
906 switch (tag)
907 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000908 case DW_TAG_inlined_subroutine:
Jim Inghamb0be4422010-08-12 01:20:14 +0000909 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000910 case DW_TAG_lexical_block:
911 {
912 DWARFDebugRanges::RangeList ranges;
913 const char *name = NULL;
914 const char *mangled_name = NULL;
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000915 Block *block = NULL;
916 if (tag != DW_TAG_subprogram)
917 {
918 BlockSP block_sp(new Block (die->GetOffset()));
919 parent_block->AddChild(block_sp);
920 block = block_sp.get();
921 }
922 else
923 {
924 block = parent_block;
925 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000926
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000927 int decl_file = 0;
928 int decl_line = 0;
929 int decl_column = 0;
930 int call_file = 0;
931 int call_line = 0;
932 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000933 if (die->GetDIENamesAndRanges (this,
934 dwarf_cu,
935 name,
936 mangled_name,
937 ranges,
938 decl_file, decl_line, decl_column,
939 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000940 {
941 if (tag == DW_TAG_subprogram)
942 {
943 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
944 subprogram_low_pc = ranges.LowestAddress(0);
945 }
Jim Inghamb0be4422010-08-12 01:20:14 +0000946 else if (tag == DW_TAG_inlined_subroutine)
947 {
948 // We get called here for inlined subroutines in two ways.
949 // The first time is when we are making the Function object
950 // for this inlined concrete instance. Since we're creating a top level block at
951 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
952 // adjust the containing address.
953 // The second time is when we are parsing the blocks inside the function that contains
954 // the inlined concrete instance. Since these will be blocks inside the containing "real"
955 // function the offset will be for that function.
956 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
957 {
958 subprogram_low_pc = ranges.LowestAddress(0);
959 }
960 }
961
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000962 AddRangesToBlock (*block, ranges, subprogram_low_pc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000963
964 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
965 {
966 std::auto_ptr<Declaration> decl_ap;
967 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +0000968 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
969 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000970
971 std::auto_ptr<Declaration> call_ap;
972 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +0000973 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
974 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000975
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000976 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000977 }
978
979 ++blocks_added;
980
981 if (parse_children && die->HasChildren())
982 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000983 blocks_added += ParseFunctionBlocks (sc,
984 block,
985 dwarf_cu,
986 die->GetFirstChild(),
987 subprogram_low_pc,
988 true,
989 true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000990 }
991 }
992 }
993 break;
994 default:
995 break;
996 }
997
998 if (parse_siblings)
999 die = die->GetSibling();
1000 else
1001 die = NULL;
1002 }
1003 return blocks_added;
1004}
1005
1006size_t
1007SymbolFileDWARF::ParseChildMembers
1008(
1009 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001010 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001011 const DWARFDebugInfoEntry *parent_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001012 clang_type_t class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001013 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001014 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1015 std::vector<int>& member_accessibilities,
Sean Callananc7fbf732010-08-06 00:32:49 +00001016 AccessType& default_accessibility,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017 bool &is_a_class
1018)
1019{
1020 if (parent_die == NULL)
1021 return 0;
1022
1023 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
1024
1025 size_t count = 0;
1026 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00001027 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
1028
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001029 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1030 {
1031 dw_tag_t tag = die->Tag();
1032
1033 switch (tag)
1034 {
1035 case DW_TAG_member:
1036 {
1037 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00001038 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001039 if (num_attributes > 0)
1040 {
1041 Declaration decl;
1042 DWARFExpression location;
1043 const char *name = NULL;
1044 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001045 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001046 off_t member_offset = 0;
1047 size_t byte_size = 0;
1048 size_t bit_offset = 0;
1049 size_t bit_size = 0;
1050 uint32_t i;
1051 for (i=0; i<num_attributes; ++i)
1052 {
1053 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1054 DWARFFormValue form_value;
1055 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1056 {
1057 switch (attr)
1058 {
1059 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1060 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1061 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1062 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1063 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1064 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1065 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1066 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1067 case DW_AT_data_member_location:
1068 if (form_value.BlockData())
1069 {
1070 Value initialValue(0);
1071 Value memberOffset(0);
1072 const DataExtractor& debug_info_data = get_debug_info_data();
1073 uint32_t block_length = form_value.Unsigned();
1074 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1075 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1076 {
1077 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1078 }
1079 }
1080 break;
1081
Greg Clayton8cf05932010-07-22 18:30:50 +00001082 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001083 case DW_AT_declaration:
1084 case DW_AT_description:
1085 case DW_AT_mutable:
1086 case DW_AT_visibility:
1087 default:
1088 case DW_AT_sibling:
1089 break;
1090 }
1091 }
1092 }
1093
1094 Type *member_type = ResolveTypeUID(encoding_uid);
1095 assert(member_type);
Sean Callananc7fbf732010-08-06 00:32:49 +00001096 if (accessibility == eAccessNone)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001097 accessibility = default_accessibility;
1098 member_accessibilities.push_back(accessibility);
1099
Greg Clayton1be10fc2010-09-29 01:12:09 +00001100 type_list->GetClangASTContext().AddFieldToRecordType (class_clang_type, name, member_type->GetClangType(), accessibility, bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001101 }
1102 }
1103 break;
1104
1105 case DW_TAG_subprogram:
Greg Clayton0fffff52010-09-24 05:15:53 +00001106 // Let the type parsing code handle this one for us...
1107 ResolveType (dwarf_cu, die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001108 break;
1109
1110 case DW_TAG_inheritance:
1111 {
1112 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00001113 if (default_accessibility == eAccessNone)
1114 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001115 // TODO: implement DW_TAG_inheritance type parsing
1116 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00001117 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001118 if (num_attributes > 0)
1119 {
1120 Declaration decl;
1121 DWARFExpression location;
1122 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001123 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001124 bool is_virtual = false;
1125 bool is_base_of_class = true;
1126 off_t member_offset = 0;
1127 uint32_t i;
1128 for (i=0; i<num_attributes; ++i)
1129 {
1130 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1131 DWARFFormValue form_value;
1132 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1133 {
1134 switch (attr)
1135 {
1136 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1137 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1138 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1139 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1140 case DW_AT_data_member_location:
1141 if (form_value.BlockData())
1142 {
1143 Value initialValue(0);
1144 Value memberOffset(0);
1145 const DataExtractor& debug_info_data = get_debug_info_data();
1146 uint32_t block_length = form_value.Unsigned();
1147 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1148 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1149 {
1150 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1151 }
1152 }
1153 break;
1154
1155 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00001156 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001157 break;
1158
1159 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1160 default:
1161 case DW_AT_sibling:
1162 break;
1163 }
1164 }
1165 }
1166
1167 Type *base_class_dctype = ResolveTypeUID(encoding_uid);
1168 assert(base_class_dctype);
Greg Clayton9e409562010-07-28 02:04:09 +00001169
1170 if (class_language == eLanguageTypeObjC)
1171 {
Greg Clayton1be10fc2010-09-29 01:12:09 +00001172 type_list->GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_dctype->GetClangType());
Greg Clayton9e409562010-07-28 02:04:09 +00001173 }
1174 else
1175 {
Greg Clayton1be10fc2010-09-29 01:12:09 +00001176 base_classes.push_back (type_list->GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetClangType(), accessibility, is_virtual, is_base_of_class));
Greg Clayton9e409562010-07-28 02:04:09 +00001177 assert(base_classes.back());
1178 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001179 }
1180 }
1181 break;
1182
1183 default:
1184 break;
1185 }
1186 }
1187 return count;
1188}
1189
1190
1191clang::DeclContext*
1192SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1193{
1194 DWARFDebugInfo* debug_info = DebugInfo();
1195 if (debug_info)
1196 {
1197 DWARFCompileUnitSP cu_sp;
1198 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1199 if (die)
1200 return GetClangDeclContextForDIE (cu_sp.get(), die);
1201 }
1202 return NULL;
1203}
1204
1205Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001206SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001207{
1208 DWARFDebugInfo* debug_info = DebugInfo();
1209 if (debug_info)
1210 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001211 DWARFCompileUnitSP cu_sp;
1212 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001213 if (type_die != NULL)
Greg Clayton594e5ed2010-09-27 21:07:38 +00001214 return ResolveType (cu_sp.get(), type_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001215 }
1216 return NULL;
1217}
1218
Greg Clayton1be10fc2010-09-29 01:12:09 +00001219lldb::clang_type_t
1220SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1221{
1222 // We have a struct/union/class/enum that needs to be fully resolved.
1223 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type);
1224 assert (die);
1225 if (die == NULL)
1226 return NULL;
1227
1228 DWARFCompileUnit *cu = DebugInfo()->GetCompileUnitContainingDIE (die->GetOffset()).get();
1229 Type *type = m_die_to_type.lookup (die);
1230
1231 const dw_tag_t tag = die->Tag();
1232
1233 assert (clang_type);
1234 DWARFDebugInfoEntry::Attributes attributes;
1235
1236 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
1237
1238 switch (tag)
1239 {
1240 case DW_TAG_structure_type:
1241 case DW_TAG_union_type:
1242 case DW_TAG_class_type:
1243 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
1244 if (die->HasChildren())
1245 {
1246 LanguageType class_language = eLanguageTypeUnknown;
1247 if (ClangASTContext::IsObjCClassType (clang_type))
1248 class_language = eLanguageTypeObjC;
1249
1250 int tag_decl_kind = -1;
1251 AccessType default_accessibility = eAccessNone;
1252 if (tag == DW_TAG_structure_type)
1253 {
1254 tag_decl_kind = clang::TTK_Struct;
1255 default_accessibility = eAccessPublic;
1256 }
1257 else if (tag == DW_TAG_union_type)
1258 {
1259 tag_decl_kind = clang::TTK_Union;
1260 default_accessibility = eAccessPublic;
1261 }
1262 else if (tag == DW_TAG_class_type)
1263 {
1264 tag_decl_kind = clang::TTK_Class;
1265 default_accessibility = eAccessPrivate;
1266 }
1267
1268 SymbolContext sc(GetCompUnitForDWARFCompUnit(cu));
1269 std::vector<clang::CXXBaseSpecifier *> base_classes;
1270 std::vector<int> member_accessibilities;
1271 bool is_a_class = false;
1272 ParseChildMembers (sc,
1273 cu,
1274 die,
1275 clang_type,
1276 class_language,
1277 base_classes,
1278 member_accessibilities,
1279 default_accessibility,
1280 is_a_class);
1281
1282 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1283 // need to tell the clang type it is actually a class.
1284 if (class_language != eLanguageTypeObjC)
1285 {
1286 if (is_a_class && tag_decl_kind != clang::TTK_Class)
1287 type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class);
1288 }
1289
1290 // Since DW_TAG_structure_type gets used for both classes
1291 // and structures, we may need to set any DW_TAG_member
1292 // fields to have a "private" access if none was specified.
1293 // When we parsed the child members we tracked that actual
1294 // accessibility value for each DW_TAG_member in the
1295 // "member_accessibilities" array. If the value for the
1296 // member is zero, then it was set to the "default_accessibility"
1297 // which for structs was "public". Below we correct this
1298 // by setting any fields to "private" that weren't correctly
1299 // set.
1300 if (is_a_class && !member_accessibilities.empty())
1301 {
1302 // This is a class and all members that didn't have
1303 // their access specified are private.
1304 type_list->GetClangASTContext().SetDefaultAccessForRecordFields (clang_type, eAccessPrivate, &member_accessibilities.front(), member_accessibilities.size());
1305 }
1306
1307 if (!base_classes.empty())
1308 {
1309 type_list->GetClangASTContext().SetBaseClassesForClassType (clang_type, &base_classes.front(), base_classes.size());
1310
1311 // Clang will copy each CXXBaseSpecifier in "base_classes"
1312 // so we have to free them all.
1313 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(), base_classes.size());
1314 }
1315
1316 }
1317 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
1318 return clang_type;
1319
1320 case DW_TAG_enumeration_type:
1321 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
1322 if (die->HasChildren())
1323 {
1324 SymbolContext sc(GetCompUnitForDWARFCompUnit(cu));
1325 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), cu, die);
1326 }
1327 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
1328 return clang_type;
1329
1330 default:
1331 assert(false && "not a forward clang type decl!");
1332 break;
1333 }
1334 return NULL;
1335}
1336
Greg Claytonc685f8e2010-09-15 04:15:46 +00001337Type*
1338SymbolFileDWARF::ResolveType (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* type_die)
1339{
1340 if (type_die != NULL)
1341 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00001342 Type *type = m_die_to_type.lookup (type_die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001343 if (type == NULL)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001344 type = GetTypeForDIE (cu, type_die).get();
Greg Clayton594e5ed2010-09-27 21:07:38 +00001345 assert (type != DIE_IS_BEING_PARSED);
1346 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001347 }
1348 return NULL;
1349}
1350
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001351CompileUnit*
Greg Clayton0fffff52010-09-24 05:15:53 +00001352SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001353{
1354 // Check if the symbol vendor already knows about this compile unit?
1355 if (cu->GetUserData() == NULL)
1356 {
1357 // The symbol vendor doesn't know about this compile unit, we
1358 // need to parse and add it to the symbol vendor object.
1359 CompUnitSP dc_cu;
1360 ParseCompileUnit(cu, dc_cu);
1361 if (dc_cu.get())
1362 {
1363 // Figure out the compile unit index if we weren't given one
Greg Clayton016a95e2010-09-14 02:20:48 +00001364 if (cu_idx == UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001365 DebugInfo()->GetCompileUnit(cu->GetOffset(), &cu_idx);
1366
1367 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
1368 }
1369 }
1370 return (CompileUnit*)cu->GetUserData();
1371}
1372
1373bool
1374SymbolFileDWARF::GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
1375{
1376 sc.Clear();
1377 // Check if the symbol vendor already knows about this compile unit?
1378 sc.module_sp = m_obj_file->GetModule()->GetSP();
Greg Clayton016a95e2010-09-14 02:20:48 +00001379 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001380
1381 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1382 if (sc.function == NULL)
1383 sc.function = ParseCompileUnitFunction(sc, cu, func_die);
1384
1385 return sc.function != NULL;
1386}
1387
1388uint32_t
1389SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1390{
1391 Timer scoped_timer(__PRETTY_FUNCTION__,
1392 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1393 so_addr.GetSection(),
1394 so_addr.GetOffset(),
1395 resolve_scope);
1396 uint32_t resolved = 0;
1397 if (resolve_scope & ( eSymbolContextCompUnit |
1398 eSymbolContextFunction |
1399 eSymbolContextBlock |
1400 eSymbolContextLineEntry))
1401 {
1402 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1403
1404 DWARFDebugAranges* debug_aranges = DebugAranges();
1405 DWARFDebugInfo* debug_info = DebugInfo();
1406 if (debug_aranges)
1407 {
1408 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1409 if (cu_offset != DW_INVALID_OFFSET)
1410 {
1411 uint32_t cu_idx;
1412 DWARFCompileUnit* cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1413 if (cu)
1414 {
1415 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1416 assert(sc.comp_unit != NULL);
1417 resolved |= eSymbolContextCompUnit;
1418
1419 if (resolve_scope & eSymbolContextLineEntry)
1420 {
1421 LineTable *line_table = sc.comp_unit->GetLineTable();
1422 if (line_table == NULL)
1423 {
1424 if (ParseCompileUnitLineTable(sc))
1425 line_table = sc.comp_unit->GetLineTable();
1426 }
1427 if (line_table != NULL)
1428 {
1429 if (so_addr.IsLinkedAddress())
1430 {
1431 Address linked_addr (so_addr);
1432 linked_addr.ResolveLinkedAddress();
1433 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1434 {
1435 resolved |= eSymbolContextLineEntry;
1436 }
1437 }
1438 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1439 {
1440 resolved |= eSymbolContextLineEntry;
1441 }
1442 }
1443 }
1444
1445 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1446 {
1447 DWARFDebugInfoEntry *function_die = NULL;
1448 DWARFDebugInfoEntry *block_die = NULL;
1449 if (resolve_scope & eSymbolContextBlock)
1450 {
1451 cu->LookupAddress(file_vm_addr, &function_die, &block_die);
1452 }
1453 else
1454 {
1455 cu->LookupAddress(file_vm_addr, &function_die, NULL);
1456 }
1457
1458 if (function_die != NULL)
1459 {
1460 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1461 if (sc.function == NULL)
1462 sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1463 }
1464
1465 if (sc.function != NULL)
1466 {
1467 resolved |= eSymbolContextFunction;
1468
1469 if (resolve_scope & eSymbolContextBlock)
1470 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001471 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001472
1473 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001474 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001475 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001476 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001477 if (sc.block)
1478 resolved |= eSymbolContextBlock;
1479 }
1480 }
1481 }
1482 }
1483 }
1484 }
1485 }
1486 return resolved;
1487}
1488
1489
1490
1491uint32_t
1492SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1493{
1494 const uint32_t prev_size = sc_list.GetSize();
1495 if (resolve_scope & eSymbolContextCompUnit)
1496 {
1497 DWARFDebugInfo* debug_info = DebugInfo();
1498 if (debug_info)
1499 {
1500 uint32_t cu_idx;
1501 DWARFCompileUnit* cu = NULL;
1502
1503 for (cu_idx = 0; (cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
1504 {
1505 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1506 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1507 if (check_inlines || file_spec_matches_cu_file_spec)
1508 {
1509 SymbolContext sc (m_obj_file->GetModule());
1510 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1511 assert(sc.comp_unit != NULL);
1512
1513 uint32_t file_idx = UINT32_MAX;
1514
1515 // If we are looking for inline functions only and we don't
1516 // find it in the support files, we are done.
1517 if (check_inlines)
1518 {
1519 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1520 if (file_idx == UINT32_MAX)
1521 continue;
1522 }
1523
1524 if (line != 0)
1525 {
1526 LineTable *line_table = sc.comp_unit->GetLineTable();
1527
1528 if (line_table != NULL && line != 0)
1529 {
1530 // We will have already looked up the file index if
1531 // we are searching for inline entries.
1532 if (!check_inlines)
1533 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1534
1535 if (file_idx != UINT32_MAX)
1536 {
1537 uint32_t found_line;
1538 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1539 found_line = sc.line_entry.line;
1540
Greg Clayton016a95e2010-09-14 02:20:48 +00001541 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001542 {
1543 sc.function = NULL;
1544 sc.block = NULL;
1545 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1546 {
1547 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1548 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1549 {
1550 DWARFDebugInfoEntry *function_die = NULL;
1551 DWARFDebugInfoEntry *block_die = NULL;
1552 cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
1553
1554 if (function_die != NULL)
1555 {
1556 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1557 if (sc.function == NULL)
1558 sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1559 }
1560
1561 if (sc.function != NULL)
1562 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001563 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001564
1565 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001566 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001567 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001568 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001569 }
1570 }
1571 }
1572
1573 sc_list.Append(sc);
1574 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1575 }
1576 }
1577 }
1578 else if (file_spec_matches_cu_file_spec && !check_inlines)
1579 {
1580 // only append the context if we aren't looking for inline call sites
1581 // by file and line and if the file spec matches that of the compile unit
1582 sc_list.Append(sc);
1583 }
1584 }
1585 else if (file_spec_matches_cu_file_spec && !check_inlines)
1586 {
1587 // only append the context if we aren't looking for inline call sites
1588 // by file and line and if the file spec matches that of the compile unit
1589 sc_list.Append(sc);
1590 }
1591
1592 if (!check_inlines)
1593 break;
1594 }
1595 }
1596 }
1597 }
1598 return sc_list.GetSize() - prev_size;
1599}
1600
1601void
1602SymbolFileDWARF::Index ()
1603{
1604 if (m_indexed)
1605 return;
1606 m_indexed = true;
1607 Timer scoped_timer (__PRETTY_FUNCTION__,
1608 "SymbolFileDWARF::Index (%s)",
1609 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1610
1611 DWARFDebugInfo* debug_info = DebugInfo();
1612 if (debug_info)
1613 {
Greg Clayton016a95e2010-09-14 02:20:48 +00001614 m_aranges.reset(new DWARFDebugAranges());
1615
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001616 uint32_t cu_idx = 0;
1617 const uint32_t num_compile_units = GetNumCompileUnits();
1618 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1619 {
1620 DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
1621
1622 bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1;
1623
Greg Claytonc685f8e2010-09-15 04:15:46 +00001624 cu->Index (cu_idx,
1625 m_function_basename_index,
1626 m_function_fullname_index,
1627 m_function_method_index,
1628 m_function_selector_index,
1629 m_global_index,
1630 m_types_index,
Greg Clayton016a95e2010-09-14 02:20:48 +00001631 DebugRanges(),
1632 m_aranges.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001633
1634 // Keep memory down by clearing DIEs if this generate function
1635 // caused them to be parsed
1636 if (clear_dies)
1637 cu->ClearDIEs (true);
1638 }
1639
Greg Clayton016a95e2010-09-14 02:20:48 +00001640 m_aranges->Sort();
Greg Claytonc685f8e2010-09-15 04:15:46 +00001641
1642#if 0
1643 StreamFile s(stdout);
1644 s.Printf("DWARF index for '%s':", GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1645 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
1646 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
1647 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
1648 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
1649 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
1650 s.Printf("\nTypes:\n"); m_types_index.Dump (&s);
1651#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001652 }
1653}
1654
1655uint32_t
1656SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1657{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001658 DWARFDebugInfo* info = DebugInfo();
1659 if (info == NULL)
1660 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001661
1662 // If we aren't appending the results to this list, then clear the list
1663 if (!append)
1664 variables.Clear();
1665
1666 // Remember how many variables are in the list before we search in case
1667 // we are appending the results to a variable list.
1668 const uint32_t original_size = variables.GetSize();
1669
1670 // Index the DWARF if we haven't already
1671 if (!m_indexed)
1672 Index ();
1673
Greg Claytonc685f8e2010-09-15 04:15:46 +00001674 SymbolContext sc;
1675 sc.module_sp = m_obj_file->GetModule()->GetSP();
1676 assert (sc.module_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001677
Greg Claytonc685f8e2010-09-15 04:15:46 +00001678 DWARFCompileUnit* cu = NULL;
1679 DWARFCompileUnit* prev_cu = NULL;
1680 const DWARFDebugInfoEntry* die = NULL;
1681 std::vector<NameToDIE::Info> die_info_array;
1682 const size_t num_matches = m_global_index.Find(name, die_info_array);
1683 for (size_t i=0; i<num_matches; ++i, prev_cu = cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001684 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001685 cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1686
1687 if (cu != prev_cu)
1688 cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001689
Greg Claytonc685f8e2010-09-15 04:15:46 +00001690 die = cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001691
Greg Claytonc685f8e2010-09-15 04:15:46 +00001692 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT32_MAX);
1693 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001694
Greg Claytonc685f8e2010-09-15 04:15:46 +00001695 ParseVariables(sc, cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
1696
1697 if (variables.GetSize() - original_size >= max_matches)
1698 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001699 }
1700
1701 // Return the number of variable that were appended to the list
1702 return variables.GetSize() - original_size;
1703}
1704
1705uint32_t
1706SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1707{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001708 DWARFDebugInfo* info = DebugInfo();
1709 if (info == NULL)
1710 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001711
1712 // If we aren't appending the results to this list, then clear the list
1713 if (!append)
1714 variables.Clear();
1715
1716 // Remember how many variables are in the list before we search in case
1717 // we are appending the results to a variable list.
1718 const uint32_t original_size = variables.GetSize();
1719
1720 // Index the DWARF if we haven't already
1721 if (!m_indexed)
1722 Index ();
1723
Greg Claytonc685f8e2010-09-15 04:15:46 +00001724 SymbolContext sc;
1725 sc.module_sp = m_obj_file->GetModule()->GetSP();
1726 assert (sc.module_sp);
1727
1728 DWARFCompileUnit* cu = NULL;
1729 DWARFCompileUnit* prev_cu = NULL;
1730 const DWARFDebugInfoEntry* die = NULL;
1731 std::vector<NameToDIE::Info> die_info_array;
1732 const size_t num_matches = m_global_index.Find(regex, die_info_array);
1733 for (size_t i=0; i<num_matches; ++i, prev_cu = cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001734 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001735 cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1736
1737 if (cu != prev_cu)
1738 cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001739
Greg Claytonc685f8e2010-09-15 04:15:46 +00001740 die = cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001741
Greg Claytonc685f8e2010-09-15 04:15:46 +00001742 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT32_MAX);
1743 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001744
Greg Claytonc685f8e2010-09-15 04:15:46 +00001745 ParseVariables(sc, cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001746
Greg Claytonc685f8e2010-09-15 04:15:46 +00001747 if (variables.GetSize() - original_size >= max_matches)
1748 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001749 }
1750
1751 // Return the number of variable that were appended to the list
1752 return variables.GetSize() - original_size;
1753}
1754
1755
Greg Clayton0c5cd902010-06-28 21:30:43 +00001756void
1757SymbolFileDWARF::FindFunctions
1758(
1759 const ConstString &name,
Greg Claytonc685f8e2010-09-15 04:15:46 +00001760 const NameToDIE &name_to_die,
Greg Clayton0c5cd902010-06-28 21:30:43 +00001761 SymbolContextList& sc_list
1762)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001763{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001764 DWARFDebugInfo* info = DebugInfo();
1765 if (info == NULL)
1766 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001767
Greg Claytonc685f8e2010-09-15 04:15:46 +00001768 SymbolContext sc;
1769 sc.module_sp = m_obj_file->GetModule()->GetSP();
1770 assert (sc.module_sp);
1771
1772 DWARFCompileUnit* cu = NULL;
1773 DWARFCompileUnit* prev_cu = NULL;
1774 const DWARFDebugInfoEntry* die = NULL;
1775 std::vector<NameToDIE::Info> die_info_array;
1776 const size_t num_matches = name_to_die.Find(name, die_info_array);
1777 for (size_t i=0; i<num_matches; ++i, prev_cu = cu)
1778 {
1779 cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1780
1781 if (cu != prev_cu)
1782 cu->ExtractDIEsIfNeeded (false);
1783
1784 die = cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
1785 if (GetFunction (cu, die, sc))
1786 {
1787 // We found the function, so we should find the line table
1788 // and line table entry as well
1789 LineTable *line_table = sc.comp_unit->GetLineTable();
1790 if (line_table == NULL)
1791 {
1792 if (ParseCompileUnitLineTable(sc))
1793 line_table = sc.comp_unit->GetLineTable();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001794 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00001795 if (line_table != NULL)
1796 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1797
1798 sc_list.Append(sc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001799 }
1800 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00001801}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001802
Greg Claytonc685f8e2010-09-15 04:15:46 +00001803
1804void
1805SymbolFileDWARF::FindFunctions
1806(
1807 const RegularExpression &regex,
1808 const NameToDIE &name_to_die,
1809 SymbolContextList& sc_list
1810)
1811{
1812 DWARFDebugInfo* info = DebugInfo();
1813 if (info == NULL)
1814 return;
1815
1816 SymbolContext sc;
1817 sc.module_sp = m_obj_file->GetModule()->GetSP();
1818 assert (sc.module_sp);
1819
1820 DWARFCompileUnit* cu = NULL;
1821 DWARFCompileUnit* prev_cu = NULL;
1822 const DWARFDebugInfoEntry* die = NULL;
1823 std::vector<NameToDIE::Info> die_info_array;
1824 const size_t num_matches = name_to_die.Find(regex, die_info_array);
1825 for (size_t i=0; i<num_matches; ++i, prev_cu = cu)
1826 {
1827 cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1828
1829 if (cu != prev_cu)
1830 cu->ExtractDIEsIfNeeded (false);
1831
1832 die = cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
1833 if (GetFunction (cu, die, sc))
1834 {
1835 // We found the function, so we should find the line table
1836 // and line table entry as well
1837 LineTable *line_table = sc.comp_unit->GetLineTable();
1838 if (line_table == NULL)
1839 {
1840 if (ParseCompileUnitLineTable(sc))
1841 line_table = sc.comp_unit->GetLineTable();
1842 }
1843 if (line_table != NULL)
1844 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1845
1846 sc_list.Append(sc);
1847 }
1848 }
Greg Clayton0c5cd902010-06-28 21:30:43 +00001849}
1850
1851uint32_t
1852SymbolFileDWARF::FindFunctions
1853(
1854 const ConstString &name,
1855 uint32_t name_type_mask,
1856 bool append,
1857 SymbolContextList& sc_list
1858)
1859{
1860 Timer scoped_timer (__PRETTY_FUNCTION__,
1861 "SymbolFileDWARF::FindFunctions (name = '%s')",
1862 name.AsCString());
1863
Greg Clayton0c5cd902010-06-28 21:30:43 +00001864 // If we aren't appending the results to this list, then clear the list
1865 if (!append)
1866 sc_list.Clear();
1867
1868 // Remember how many sc_list are in the list before we search in case
1869 // we are appending the results to a variable list.
1870 uint32_t original_size = sc_list.GetSize();
1871
1872 // Index the DWARF if we haven't already
1873 if (!m_indexed)
1874 Index ();
1875
1876 if (name_type_mask & eFunctionNameTypeBase)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001877 FindFunctions (name, m_function_basename_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00001878
1879 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001880 FindFunctions (name, m_function_fullname_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00001881
1882 if (name_type_mask & eFunctionNameTypeMethod)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001883 FindFunctions (name, m_function_method_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00001884
1885 if (name_type_mask & eFunctionNameTypeSelector)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001886 FindFunctions (name, m_function_selector_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00001887
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001888 // Return the number of variable that were appended to the list
1889 return sc_list.GetSize() - original_size;
1890}
1891
1892
1893uint32_t
1894SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
1895{
1896 Timer scoped_timer (__PRETTY_FUNCTION__,
1897 "SymbolFileDWARF::FindFunctions (regex = '%s')",
1898 regex.GetText());
1899
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001900 // If we aren't appending the results to this list, then clear the list
1901 if (!append)
1902 sc_list.Clear();
1903
1904 // Remember how many sc_list are in the list before we search in case
1905 // we are appending the results to a variable list.
1906 uint32_t original_size = sc_list.GetSize();
1907
1908 // Index the DWARF if we haven't already
1909 if (!m_indexed)
1910 Index ();
1911
Greg Claytonc685f8e2010-09-15 04:15:46 +00001912 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001913
Greg Claytonc685f8e2010-09-15 04:15:46 +00001914 FindFunctions (regex, m_function_fullname_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001915
1916 // Return the number of variable that were appended to the list
1917 return sc_list.GetSize() - original_size;
1918}
1919
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001920uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001921SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001922{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001923 DWARFDebugInfo* info = DebugInfo();
1924 if (info == NULL)
1925 return 0;
1926
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001927 // If we aren't appending the results to this list, then clear the list
1928 if (!append)
1929 types.Clear();
1930
Greg Clayton6dbd3982010-09-15 05:51:24 +00001931 // Index if we already haven't to make sure the compile units
1932 // get indexed and make their global DIE index list
1933 if (!m_indexed)
1934 Index ();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001935
Greg Claytonc685f8e2010-09-15 04:15:46 +00001936 const uint32_t initial_types_size = types.GetSize();
1937 DWARFCompileUnit* cu = NULL;
1938 DWARFCompileUnit* prev_cu = NULL;
1939 const DWARFDebugInfoEntry* die = NULL;
1940 std::vector<NameToDIE::Info> die_info_array;
1941 const size_t num_matches = m_types_index.Find (name, die_info_array);
1942 for (size_t i=0; i<num_matches; ++i, prev_cu = cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001943 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001944 cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1945
1946 if (cu != prev_cu)
1947 cu->ExtractDIEsIfNeeded (false);
1948
1949 die = cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
1950
1951 Type *matching_type = ResolveType (cu, die);
1952 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001953 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001954 // We found a type pointer, now find the shared pointer form our type list
1955 TypeSP type_sp (m_obj_file->GetModule()->GetTypeList()->FindType(matching_type->GetID()));
1956 assert (type_sp.get() != NULL);
1957 types.InsertUnique (type_sp);
1958 if (types.GetSize() >= max_matches)
1959 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001960 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001961 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00001962 return types.GetSize() - initial_types_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001963}
1964
1965
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001966uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001967SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001968{
1969 // Remember how many sc_list are in the list before we search in case
1970 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001971 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001972
1973 const uint32_t num_die_offsets = die_offsets.size();
1974 // Parse all of the types we found from the pubtypes matches
1975 uint32_t i;
1976 uint32_t num_matches = 0;
1977 for (i = 0; i < num_die_offsets; ++i)
1978 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001979 Type *matching_type = ResolveTypeUID (die_offsets[i]);
1980 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001981 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001982 // We found a type pointer, now find the shared pointer form our type list
1983 TypeSP type_sp (m_obj_file->GetModule()->GetTypeList()->FindType(matching_type->GetID()));
1984 assert (type_sp.get() != NULL);
1985 types.InsertUnique (type_sp);
1986 ++num_matches;
1987 if (num_matches >= max_matches)
1988 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001989 }
1990 }
1991
1992 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00001993 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001994}
1995
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001996
1997size_t
1998SymbolFileDWARF::ParseChildParameters
1999(
2000 const SymbolContext& sc,
2001 TypeSP& type_sp,
Greg Clayton0fffff52010-09-24 05:15:53 +00002002 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002003 const DWARFDebugInfoEntry *parent_die,
Greg Claytona51ed9b2010-09-23 01:09:21 +00002004 bool skip_artificial,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002005 TypeList* type_list,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002006 std::vector<clang_type_t>& function_param_types,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002007 std::vector<clang::ParmVarDecl*>& function_param_decls
2008)
2009{
2010 if (parent_die == NULL)
2011 return 0;
2012
Greg Claytond88d7592010-09-15 08:33:30 +00002013 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2014
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002015 size_t count = 0;
2016 const DWARFDebugInfoEntry *die;
2017 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2018 {
2019 dw_tag_t tag = die->Tag();
2020 switch (tag)
2021 {
2022 case DW_TAG_formal_parameter:
2023 {
2024 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002025 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002026 if (num_attributes > 0)
2027 {
2028 const char *name = NULL;
2029 Declaration decl;
2030 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002031 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002032 // one of None, Auto, Register, Extern, Static, PrivateExtern
2033
Sean Callanane2ef6e32010-09-23 03:01:22 +00002034 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002035 uint32_t i;
2036 for (i=0; i<num_attributes; ++i)
2037 {
2038 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2039 DWARFFormValue form_value;
2040 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2041 {
2042 switch (attr)
2043 {
2044 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2045 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2046 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2047 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2048 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002049 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002050 case DW_AT_location:
2051 // if (form_value.BlockData())
2052 // {
2053 // const DataExtractor& debug_info_data = debug_info();
2054 // uint32_t block_length = form_value.Unsigned();
2055 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2056 // }
2057 // else
2058 // {
2059 // }
2060 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002061 case DW_AT_const_value:
2062 case DW_AT_default_value:
2063 case DW_AT_description:
2064 case DW_AT_endianity:
2065 case DW_AT_is_optional:
2066 case DW_AT_segment:
2067 case DW_AT_variable_parameter:
2068 default:
2069 case DW_AT_abstract_origin:
2070 case DW_AT_sibling:
2071 break;
2072 }
2073 }
2074 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00002075
Greg Clayton0fffff52010-09-24 05:15:53 +00002076 bool skip = false;
2077 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002078 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002079 if (is_artificial)
2080 skip = true;
2081 else
2082 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002083
Greg Clayton0fffff52010-09-24 05:15:53 +00002084 // HACK: Objective C formal parameters "self" and "_cmd"
2085 // are not marked as artificial in the DWARF...
2086 CompileUnit *cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2087 if (cu && (cu->GetLanguage() == eLanguageTypeObjC || cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
2088 {
2089 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2090 skip = true;
2091 }
2092 }
2093 }
2094
2095 if (!skip)
2096 {
2097 Type *type = ResolveTypeUID(param_type_die_offset);
2098 if (type)
2099 {
Greg Clayton1be10fc2010-09-29 01:12:09 +00002100 function_param_types.push_back (type->GetClangType(true));
Greg Clayton0fffff52010-09-24 05:15:53 +00002101
Greg Clayton1be10fc2010-09-29 01:12:09 +00002102 clang::ParmVarDecl *param_var_decl = type_list->GetClangASTContext().CreateParameterDeclaration (name, type->GetClangType(), storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00002103 assert(param_var_decl);
2104 function_param_decls.push_back(param_var_decl);
2105 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002106 }
2107 }
2108 }
2109 break;
2110
2111 default:
2112 break;
2113 }
2114 }
2115 return count;
2116}
2117
2118size_t
2119SymbolFileDWARF::ParseChildEnumerators
2120(
2121 const SymbolContext& sc,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002122 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002123 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00002124 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002125 const DWARFDebugInfoEntry *parent_die
2126)
2127{
2128 if (parent_die == NULL)
2129 return 0;
2130
2131 size_t enumerators_added = 0;
2132 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002133 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2134
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002135 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2136 {
2137 const dw_tag_t tag = die->Tag();
2138 if (tag == DW_TAG_enumerator)
2139 {
2140 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002141 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002142 if (num_child_attributes > 0)
2143 {
2144 const char *name = NULL;
2145 bool got_value = false;
2146 int64_t enum_value = 0;
2147 Declaration decl;
2148
2149 uint32_t i;
2150 for (i=0; i<num_child_attributes; ++i)
2151 {
2152 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2153 DWARFFormValue form_value;
2154 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2155 {
2156 switch (attr)
2157 {
2158 case DW_AT_const_value:
2159 got_value = true;
2160 enum_value = form_value.Unsigned();
2161 break;
2162
2163 case DW_AT_name:
2164 name = form_value.AsCString(&get_debug_str_data());
2165 break;
2166
2167 case DW_AT_description:
2168 default:
2169 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2170 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2171 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2172 case DW_AT_sibling:
2173 break;
2174 }
2175 }
2176 }
2177
2178 if (name && name[0] && got_value)
2179 {
2180 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
Greg Clayton1be10fc2010-09-29 01:12:09 +00002181 type_list->GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2182 enumerator_clang_type,
2183 decl,
2184 name,
2185 enum_value,
2186 enumerator_byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002187 ++enumerators_added;
2188 }
2189 }
2190 }
2191 }
2192 return enumerators_added;
2193}
2194
2195void
2196SymbolFileDWARF::ParseChildArrayInfo
2197(
2198 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00002199 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002200 const DWARFDebugInfoEntry *parent_die,
2201 int64_t& first_index,
2202 std::vector<uint64_t>& element_orders,
2203 uint32_t& byte_stride,
2204 uint32_t& bit_stride
2205)
2206{
2207 if (parent_die == NULL)
2208 return;
2209
2210 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002211 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002212 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2213 {
2214 const dw_tag_t tag = die->Tag();
2215 switch (tag)
2216 {
2217 case DW_TAG_enumerator:
2218 {
2219 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002220 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002221 if (num_child_attributes > 0)
2222 {
2223 const char *name = NULL;
2224 bool got_value = false;
2225 int64_t enum_value = 0;
2226
2227 uint32_t i;
2228 for (i=0; i<num_child_attributes; ++i)
2229 {
2230 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2231 DWARFFormValue form_value;
2232 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2233 {
2234 switch (attr)
2235 {
2236 case DW_AT_const_value:
2237 got_value = true;
2238 enum_value = form_value.Unsigned();
2239 break;
2240
2241 case DW_AT_name:
2242 name = form_value.AsCString(&get_debug_str_data());
2243 break;
2244
2245 case DW_AT_description:
2246 default:
2247 case DW_AT_decl_file:
2248 case DW_AT_decl_line:
2249 case DW_AT_decl_column:
2250 case DW_AT_sibling:
2251 break;
2252 }
2253 }
2254 }
2255 }
2256 }
2257 break;
2258
2259 case DW_TAG_subrange_type:
2260 {
2261 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002262 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002263 if (num_child_attributes > 0)
2264 {
2265 const char *name = NULL;
2266 bool got_value = false;
2267 uint64_t byte_size = 0;
2268 int64_t enum_value = 0;
2269 uint64_t num_elements = 0;
2270 uint64_t lower_bound = 0;
2271 uint64_t upper_bound = 0;
2272 uint32_t i;
2273 for (i=0; i<num_child_attributes; ++i)
2274 {
2275 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2276 DWARFFormValue form_value;
2277 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2278 {
2279 switch (attr)
2280 {
2281 case DW_AT_const_value:
2282 got_value = true;
2283 enum_value = form_value.Unsigned();
2284 break;
2285
2286 case DW_AT_name:
2287 name = form_value.AsCString(&get_debug_str_data());
2288 break;
2289
2290 case DW_AT_count:
2291 num_elements = form_value.Unsigned();
2292 break;
2293
2294 case DW_AT_bit_stride:
2295 bit_stride = form_value.Unsigned();
2296 break;
2297
2298 case DW_AT_byte_stride:
2299 byte_stride = form_value.Unsigned();
2300 break;
2301
2302 case DW_AT_byte_size:
2303 byte_size = form_value.Unsigned();
2304 break;
2305
2306 case DW_AT_lower_bound:
2307 lower_bound = form_value.Unsigned();
2308 break;
2309
2310 case DW_AT_upper_bound:
2311 upper_bound = form_value.Unsigned();
2312 break;
2313
2314 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002315 case DW_AT_abstract_origin:
2316 case DW_AT_accessibility:
2317 case DW_AT_allocated:
2318 case DW_AT_associated:
2319 case DW_AT_data_location:
2320 case DW_AT_declaration:
2321 case DW_AT_description:
2322 case DW_AT_sibling:
2323 case DW_AT_threads_scaled:
2324 case DW_AT_type:
2325 case DW_AT_visibility:
2326 break;
2327 }
2328 }
2329 }
2330
2331 if (upper_bound > lower_bound)
2332 num_elements = upper_bound - lower_bound + 1;
2333
2334 if (num_elements > 0)
2335 element_orders.push_back (num_elements);
2336 }
2337 }
2338 break;
2339 }
2340 }
2341}
2342
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002343TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00002344SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002345{
2346 TypeSP type_sp;
2347 if (die != NULL)
2348 {
2349 assert(cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00002350 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002351 if (type_ptr == NULL)
2352 {
2353 SymbolContext sc(GetCompUnitForDWARFCompUnit(cu));
Greg Clayton1be10fc2010-09-29 01:12:09 +00002354 type_sp = ParseType(sc, cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002355 }
2356 else if (type_ptr != DIE_IS_BEING_PARSED)
2357 {
2358 // Grab the existing type from the master types lists
2359 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(type_ptr->GetID());
2360 }
2361
2362 }
2363 return type_sp;
2364}
2365
2366clang::DeclContext *
2367SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2368{
2369 if (die_offset != DW_INVALID_OFFSET)
2370 {
2371 DWARFCompileUnitSP cu_sp;
2372 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2373 return GetClangDeclContextForDIE (cu_sp.get(), die);
2374 }
2375 return NULL;
2376}
2377
2378
2379
2380clang::DeclContext *
Greg Clayton0fffff52010-09-24 05:15:53 +00002381SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002382{
2383 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2384 if (pos != m_die_to_decl_ctx.end())
2385 return pos->second;
2386
2387 while (die != NULL)
2388 {
2389 switch (die->Tag())
2390 {
2391 case DW_TAG_namespace:
2392 {
2393 const char *namespace_name = die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL);
2394 if (namespace_name)
2395 {
2396 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2397 assert(type_list);
2398 Declaration decl; // TODO: fill in the decl object
2399 clang::NamespaceDecl *namespace_decl = type_list->GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (cu, die->GetParent()));
2400 if (namespace_decl)
2401 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2402 return namespace_decl;
2403 }
2404 }
2405 break;
2406
2407 default:
2408 break;
2409 }
2410 clang::DeclContext *decl_ctx;
2411 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_specification, DW_INVALID_OFFSET));
2412 if (decl_ctx)
2413 return decl_ctx;
2414
2415 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET));
2416 if (decl_ctx)
2417 return decl_ctx;
2418
2419 die = die->GetParent();
2420 }
2421 return NULL;
2422}
2423
2424TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00002425SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002426{
2427 TypeSP type_sp;
2428
Greg Clayton1be10fc2010-09-29 01:12:09 +00002429 if (type_is_new_ptr)
2430 *type_is_new_ptr = false;
2431
Sean Callananc7fbf732010-08-06 00:32:49 +00002432 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002433 if (die != NULL)
2434 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00002435 Type *type_ptr = m_die_to_type.lookup (die);
2436 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002437 {
Greg Clayton1be10fc2010-09-29 01:12:09 +00002438 if (type_is_new_ptr)
2439 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002440
Greg Clayton594e5ed2010-09-27 21:07:38 +00002441 const dw_tag_t tag = die->Tag();
2442
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002443 bool is_forward_declaration = false;
2444 DWARFDebugInfoEntry::Attributes attributes;
2445 const char *type_name_cstr = NULL;
2446 ConstString type_name_dbstr;
Greg Clayton4957bf62010-09-30 21:49:03 +00002447 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002448 clang_type_t clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002449
2450 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2451 dw_attr_t attr;
2452
2453 switch (tag)
2454 {
2455 case DW_TAG_base_type:
2456 case DW_TAG_pointer_type:
2457 case DW_TAG_reference_type:
2458 case DW_TAG_typedef:
2459 case DW_TAG_const_type:
2460 case DW_TAG_restrict_type:
2461 case DW_TAG_volatile_type:
2462 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002463 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002464 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002465
Greg Claytond88d7592010-09-15 08:33:30 +00002466 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002467 Declaration decl;
2468 uint32_t encoding = 0;
2469 size_t byte_size = 0;
2470 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
2471
2472 if (num_attributes > 0)
2473 {
2474 uint32_t i;
2475 for (i=0; i<num_attributes; ++i)
2476 {
2477 attr = attributes.AttributeAtIndex(i);
2478 DWARFFormValue form_value;
2479 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2480 {
2481 switch (attr)
2482 {
2483 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2484 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2485 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2486 case DW_AT_name:
2487 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2488 type_name_dbstr.SetCString(type_name_cstr);
2489 break;
2490 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
2491 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
2492 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2493 default:
2494 case DW_AT_sibling:
2495 break;
2496 }
2497 }
2498 }
2499 }
2500
2501 switch (tag)
2502 {
2503 default:
2504 case DW_TAG_base_type:
2505 clang_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, encoding, byte_size * 8);
2506 break;
2507
2508 case DW_TAG_pointer_type:
2509 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002510 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002511 encoding_data_type = Type::eEncodingIsPointerUID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002512 break;
2513
2514 case DW_TAG_reference_type:
2515 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002516 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002517 encoding_data_type = Type::eEncodingIsLValueReferenceUID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002518 break;
2519
2520 case DW_TAG_typedef:
2521 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002522 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002523 encoding_data_type = Type::eEncodingIsTypedefUID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002524 break;
2525
2526 case DW_TAG_const_type:
2527 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002528 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002529 encoding_data_type = Type::eEncodingIsConstUID; //ClangASTContext::AddConstModifier (clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002530 break;
2531
2532 case DW_TAG_restrict_type:
2533 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002534 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002535 encoding_data_type = Type::eEncodingIsRestrictUID; //ClangASTContext::AddRestrictModifier (clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002536 break;
2537
2538 case DW_TAG_volatile_type:
2539 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002540 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002541 encoding_data_type = Type::eEncodingIsVolatileUID; //ClangASTContext::AddVolatileModifier (clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002542 break;
2543 }
2544
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002545 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
2546 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
2547 {
2548 static ConstString g_objc_type_name_id("id");
2549 static ConstString g_objc_type_name_Class("Class");
2550 static ConstString g_objc_type_name_selector("SEL");
2551
2552 if (type_name_dbstr == g_objc_type_name_id)
2553 {
2554 clang_type = type_list->GetClangASTContext().GetBuiltInType_objc_id();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002555 }
2556 else if (type_name_dbstr == g_objc_type_name_Class)
2557 {
2558 clang_type = type_list->GetClangASTContext().GetBuiltInType_objc_Class();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002559 }
2560 else if (type_name_dbstr == g_objc_type_name_selector)
2561 {
2562 clang_type = type_list->GetClangASTContext().GetBuiltInType_objc_selector();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002563 }
2564 }
2565
Greg Clayton4957bf62010-09-30 21:49:03 +00002566 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, encoding_data_type, &decl, clang_type, clang_type == NULL));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002567
Greg Clayton594e5ed2010-09-27 21:07:38 +00002568 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002569
2570// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
2571// if (encoding_type != NULL)
2572// {
2573// if (encoding_type != DIE_IS_BEING_PARSED)
2574// type_sp->SetEncodingType(encoding_type);
2575// else
2576// m_indirect_fixups.push_back(type_sp.get());
2577// }
2578 }
2579 break;
2580
2581 case DW_TAG_structure_type:
2582 case DW_TAG_union_type:
2583 case DW_TAG_class_type:
2584 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002585 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002586 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002587
2588 size_t byte_size = 0;
Greg Clayton9e409562010-07-28 02:04:09 +00002589 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002590 //bool struct_is_class = false;
2591 Declaration decl;
Greg Claytond88d7592010-09-15 08:33:30 +00002592 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002593 if (num_attributes > 0)
2594 {
2595 uint32_t i;
2596 for (i=0; i<num_attributes; ++i)
2597 {
2598 attr = attributes.AttributeAtIndex(i);
2599 DWARFFormValue form_value;
2600 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2601 {
2602 switch (attr)
2603 {
Greg Clayton9e409562010-07-28 02:04:09 +00002604 case DW_AT_decl_file:
2605 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
2606 break;
2607
2608 case DW_AT_decl_line:
2609 decl.SetLine(form_value.Unsigned());
2610 break;
2611
2612 case DW_AT_decl_column:
2613 decl.SetColumn(form_value.Unsigned());
2614 break;
2615
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002616 case DW_AT_name:
2617 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2618 type_name_dbstr.SetCString(type_name_cstr);
2619 break;
Greg Clayton9e409562010-07-28 02:04:09 +00002620
2621 case DW_AT_byte_size:
2622 byte_size = form_value.Unsigned();
2623 break;
2624
2625 case DW_AT_accessibility:
2626 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
2627 break;
2628
2629 case DW_AT_declaration:
2630 is_forward_declaration = form_value.Unsigned() != 0;
2631 break;
2632
2633 case DW_AT_APPLE_runtime_class:
2634 class_language = (LanguageType)form_value.Signed();
2635 break;
2636
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002637 case DW_AT_allocated:
2638 case DW_AT_associated:
2639 case DW_AT_data_location:
2640 case DW_AT_description:
2641 case DW_AT_start_scope:
2642 case DW_AT_visibility:
2643 default:
2644 case DW_AT_sibling:
2645 break;
2646 }
2647 }
2648 }
2649 }
2650
2651 int tag_decl_kind = -1;
Sean Callananc7fbf732010-08-06 00:32:49 +00002652 AccessType default_accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002653 if (tag == DW_TAG_structure_type)
2654 {
2655 tag_decl_kind = clang::TTK_Struct;
Sean Callananc7fbf732010-08-06 00:32:49 +00002656 default_accessibility = eAccessPublic;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002657 }
2658 else if (tag == DW_TAG_union_type)
2659 {
2660 tag_decl_kind = clang::TTK_Union;
Sean Callananc7fbf732010-08-06 00:32:49 +00002661 default_accessibility = eAccessPublic;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002662 }
2663 else if (tag == DW_TAG_class_type)
2664 {
2665 tag_decl_kind = clang::TTK_Class;
Sean Callananc7fbf732010-08-06 00:32:49 +00002666 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002667 }
2668
2669 assert (tag_decl_kind != -1);
Greg Clayton1be10fc2010-09-29 01:12:09 +00002670 bool clang_type_was_created = false;
2671 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
2672 if (clang_type == NULL)
2673 {
2674 clang_type_was_created = true;
2675 clang_type = type_list->GetClangASTContext().CreateRecordType (type_name_cstr, tag_decl_kind, GetClangDeclContextForDIE (dwarf_cu, die), class_language);
2676 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002677
Greg Clayton6adffa22010-09-28 01:04:25 +00002678 // Store a forward declaration to this class type in case any
2679 // parameters in any class methods need it for the clang
2680 // types for function prototypes.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002681 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
Greg Clayton16c880f2010-09-30 22:25:09 +00002682 const bool is_forward_decl = die->HasChildren();
2683 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, clang_type, is_forward_decl));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002684
Greg Clayton594e5ed2010-09-27 21:07:38 +00002685 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002686
Greg Clayton4957bf62010-09-30 21:49:03 +00002687 if (die->HasChildren() == false)
Greg Clayton1be10fc2010-09-29 01:12:09 +00002688 {
Greg Clayton4957bf62010-09-30 21:49:03 +00002689 // No children for this struct/union/class, lets finish it
2690 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
2691 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
2692 }
2693 else if (clang_type_was_created)
2694 {
2695 // Leave this as a forward declaration until we need
2696 // to know the details of the type. lldb_private::Type
2697 // will automatically call the SymbolFile virtual function
2698 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
2699 // When the definition needs to be defined.
Greg Clayton1be10fc2010-09-29 01:12:09 +00002700 m_forward_decl_die_to_clang_type[die] = clang_type;
2701 m_forward_decl_clang_type_to_die[clang_type] = die;
2702 }
Greg Clayton4957bf62010-09-30 21:49:03 +00002703
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002704 }
2705 break;
2706
2707 case DW_TAG_enumeration_type:
2708 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002709 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002710 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002711
2712 size_t byte_size = 0;
2713 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
2714 Declaration decl;
2715
Greg Claytond88d7592010-09-15 08:33:30 +00002716 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002717 if (num_attributes > 0)
2718 {
2719 uint32_t i;
2720
2721 for (i=0; i<num_attributes; ++i)
2722 {
2723 attr = attributes.AttributeAtIndex(i);
2724 DWARFFormValue form_value;
2725 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2726 {
2727 switch (attr)
2728 {
2729 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2730 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2731 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2732 case DW_AT_name:
2733 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2734 type_name_dbstr.SetCString(type_name_cstr);
2735 break;
2736 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2737 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00002738 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002739 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
2740 case DW_AT_allocated:
2741 case DW_AT_associated:
2742 case DW_AT_bit_stride:
2743 case DW_AT_byte_stride:
2744 case DW_AT_data_location:
2745 case DW_AT_description:
2746 case DW_AT_start_scope:
2747 case DW_AT_visibility:
2748 case DW_AT_specification:
2749 case DW_AT_abstract_origin:
2750 case DW_AT_sibling:
2751 break;
2752 }
2753 }
2754 }
2755
Greg Clayton1be10fc2010-09-29 01:12:09 +00002756 clang_type_t enumerator_clang_type = NULL;
2757 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
2758 if (clang_type == NULL)
2759 {
2760 enumerator_clang_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, DW_ATE_signed, byte_size * 8);
2761 clang_type = type_list->GetClangASTContext().CreateEnumerationType(decl, type_name_cstr, enumerator_clang_type);
2762 }
2763 else
2764 {
2765 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
2766 assert (enumerator_clang_type != NULL);
2767 }
2768
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002769 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
Greg Clayton4957bf62010-09-30 21:49:03 +00002770 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, Type::eEncodingIsUID, &decl, clang_type, true));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002771
Greg Clayton594e5ed2010-09-27 21:07:38 +00002772 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002773
Greg Clayton1be10fc2010-09-29 01:12:09 +00002774 // Leave this as a forward declaration until we need
2775 // to know the details of the type. lldb_private::Type
2776 // will automatically call the SymbolFile virtual function
2777 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
2778 // When the definition needs to be defined.
2779 m_forward_decl_die_to_clang_type[die] = clang_type;
2780 m_forward_decl_clang_type_to_die[clang_type] = die;
2781
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002782 }
2783 }
2784 break;
2785
Jim Inghamb0be4422010-08-12 01:20:14 +00002786 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002787 case DW_TAG_subprogram:
2788 case DW_TAG_subroutine_type:
2789 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002790 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002791 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002792
2793 const char *mangled = NULL;
2794 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
2795 Declaration decl;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002796 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002797 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00002798 bool is_static = false;
2799 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00002800 bool is_explicit = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00002801
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002802 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00002803 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002804
2805
Greg Claytond88d7592010-09-15 08:33:30 +00002806 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002807 if (num_attributes > 0)
2808 {
2809 uint32_t i;
2810 for (i=0; i<num_attributes; ++i)
2811 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002812 const dw_attr_t attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002813 DWARFFormValue form_value;
2814 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2815 {
2816 switch (attr)
2817 {
2818 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2819 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2820 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2821 case DW_AT_name:
2822 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2823 type_name_dbstr.SetCString(type_name_cstr);
2824 break;
2825
2826 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
2827 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00002828 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002829 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00002830 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
2831 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Claytonf51de672010-10-01 02:31:07 +00002832 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
2833
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002834 case DW_AT_external:
2835 if (form_value.Unsigned())
2836 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00002837 if (storage == clang::SC_None)
2838 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002839 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00002840 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002841 }
2842 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002843
2844 case DW_AT_allocated:
2845 case DW_AT_associated:
2846 case DW_AT_address_class:
2847 case DW_AT_artificial:
2848 case DW_AT_calling_convention:
2849 case DW_AT_data_location:
2850 case DW_AT_elemental:
2851 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002852 case DW_AT_frame_base:
2853 case DW_AT_high_pc:
2854 case DW_AT_low_pc:
2855 case DW_AT_object_pointer:
2856 case DW_AT_prototyped:
2857 case DW_AT_pure:
2858 case DW_AT_ranges:
2859 case DW_AT_recursive:
2860 case DW_AT_return_addr:
2861 case DW_AT_segment:
2862 case DW_AT_specification:
2863 case DW_AT_start_scope:
2864 case DW_AT_static_link:
2865 case DW_AT_trampoline:
2866 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002867 case DW_AT_vtable_elem_location:
2868 case DW_AT_abstract_origin:
2869 case DW_AT_description:
2870 case DW_AT_sibling:
2871 break;
2872 }
2873 }
2874 }
2875
Greg Clayton1be10fc2010-09-29 01:12:09 +00002876 clang_type_t return_clang_type = NULL;
Greg Claytonf51de672010-10-01 02:31:07 +00002877 Type *func_type = NULL;
2878
2879 if (type_die_offset != DW_INVALID_OFFSET)
2880 func_type = ResolveTypeUID(type_die_offset);
2881
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002882 if (func_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00002883 return_clang_type = func_type->GetClangType(true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002884 else
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002885 return_clang_type = type_list->GetClangASTContext().GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002886
Greg Claytonf51de672010-10-01 02:31:07 +00002887
Greg Clayton1be10fc2010-09-29 01:12:09 +00002888 std::vector<clang_type_t> function_param_types;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002889 std::vector<clang::ParmVarDecl*> function_param_decls;
2890
2891 // Parse the function children for the parameters
Greg Clayton0fffff52010-09-24 05:15:53 +00002892 bool skip_artificial = true;
2893 ParseChildParameters (sc, type_sp, dwarf_cu, die, skip_artificial, type_list, function_param_types, function_param_decls);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002894
Greg Clayton0fffff52010-09-24 05:15:53 +00002895 // clang_type will get the function prototype clang type after this call
Greg Claytona51ed9b2010-09-23 01:09:21 +00002896 clang_type = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), is_variadic, type_quals);
Greg Claytonf51de672010-10-01 02:31:07 +00002897
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002898 if (type_name_cstr)
2899 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002900 bool type_handled = false;
2901 const DWARFDebugInfoEntry *parent_die = die->GetParent();
2902 if (tag == DW_TAG_subprogram)
2903 {
2904 if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+'))
2905 {
2906 // We need to find the DW_TAG_class_type or
2907 // DW_TAG_struct_type by name so we can add this
2908 // as a member function of the class.
2909 const char *class_name_start = type_name_cstr + 2;
2910 const char *class_name_end = ::strchr (class_name_start, ' ');
2911 SymbolContext empty_sc;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002912 clang_type_t class_opaque_type = NULL;
Greg Clayton0fffff52010-09-24 05:15:53 +00002913 if (class_name_start < class_name_end)
2914 {
2915 ConstString class_name (class_name_start, class_name_end - class_name_start);
2916 TypeList types;
2917 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
2918 if (match_count > 0)
2919 {
2920 for (uint32_t i=0; i<match_count; ++i)
2921 {
2922 Type *type = types.GetTypeAtIndex (i).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00002923 if (ClangASTContext::IsObjCClassType (type->GetClangType()))
Greg Clayton0fffff52010-09-24 05:15:53 +00002924 {
Greg Clayton1be10fc2010-09-29 01:12:09 +00002925 class_opaque_type = type->GetClangType();
Greg Clayton0fffff52010-09-24 05:15:53 +00002926 break;
2927 }
2928 }
2929 }
2930 }
2931
2932 if (class_opaque_type)
2933 {
Greg Clayton6d01ad92010-09-29 01:57:37 +00002934 // If accessibility isn't set to anything valid, assume public for
2935 // now...
2936 if (accessibility == eAccessNone)
2937 accessibility = eAccessPublic;
2938
Greg Clayton0fffff52010-09-24 05:15:53 +00002939 clang::ObjCMethodDecl *objc_method_decl;
2940 objc_method_decl = type_list->GetClangASTContext().AddMethodToObjCObjectType (class_opaque_type,
2941 type_name_cstr,
2942 clang_type,
2943 accessibility);
2944 type_handled = objc_method_decl != NULL;
2945 }
2946 }
2947 else if (parent_die->Tag() == DW_TAG_class_type ||
2948 parent_die->Tag() == DW_TAG_structure_type)
2949 {
2950 // Look at the parent of this DIE and see if is is
2951 // a class or struct and see if this is actually a
2952 // C++ method
2953 Type *class_type = ResolveType (dwarf_cu, parent_die);
2954 if (class_type)
2955 {
Greg Clayton1be10fc2010-09-29 01:12:09 +00002956 clang_type_t class_opaque_type = class_type->GetClangType (true);
Greg Clayton0fffff52010-09-24 05:15:53 +00002957 if (ClangASTContext::IsCXXClassType (class_opaque_type))
2958 {
Greg Clayton6d01ad92010-09-29 01:57:37 +00002959 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
2960 // in the DWARF for C++ methods... Default to public for now...
2961 if (accessibility == eAccessNone)
2962 accessibility = eAccessPublic;
2963
Greg Clayton0fffff52010-09-24 05:15:53 +00002964 clang::CXXMethodDecl *cxx_method_decl;
2965 cxx_method_decl = type_list->GetClangASTContext().AddMethodToCXXRecordType (class_opaque_type,
2966 type_name_cstr,
2967 clang_type,
2968 accessibility,
2969 is_virtual,
2970 is_static,
Greg Claytonf51de672010-10-01 02:31:07 +00002971 is_inline,
2972 is_explicit);
Greg Clayton0fffff52010-09-24 05:15:53 +00002973 type_handled = cxx_method_decl != NULL;
2974 }
2975 }
2976 }
2977 }
2978
2979 if (!type_handled)
2980 {
2981 // We just have a function that isn't part of a class
2982 clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline);
2983
2984 // Add the decl to our DIE to decl context map
2985 assert (function_decl);
2986 m_die_to_decl_ctx[die] = function_decl;
2987 if (!function_param_decls.empty())
2988 type_list->GetClangASTContext().SetFunctionParameters (function_decl, &function_param_decls.front(), function_param_decls.size());
2989 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002990 }
Greg Clayton4957bf62010-09-30 21:49:03 +00002991 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, 0, NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, clang_type, false));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002992
Greg Clayton594e5ed2010-09-27 21:07:38 +00002993 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002994 assert(type_sp.get());
2995 }
2996 }
2997 break;
2998
2999 case DW_TAG_array_type:
3000 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003001 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003002 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003003
3004 size_t byte_size = 0;
3005 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
3006 Declaration decl;
3007 int64_t first_index = 0;
3008 uint32_t byte_stride = 0;
3009 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00003010 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003011
3012 if (num_attributes > 0)
3013 {
3014 uint32_t i;
3015 for (i=0; i<num_attributes; ++i)
3016 {
3017 attr = attributes.AttributeAtIndex(i);
3018 DWARFFormValue form_value;
3019 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3020 {
3021 switch (attr)
3022 {
3023 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3024 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3025 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3026 case DW_AT_name:
3027 type_name_cstr = form_value.AsCString(&get_debug_str_data());
3028 type_name_dbstr.SetCString(type_name_cstr);
3029 break;
3030
3031 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
3032 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3033 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3034 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003035 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003036 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
3037 case DW_AT_allocated:
3038 case DW_AT_associated:
3039 case DW_AT_data_location:
3040 case DW_AT_description:
3041 case DW_AT_ordering:
3042 case DW_AT_start_scope:
3043 case DW_AT_visibility:
3044 case DW_AT_specification:
3045 case DW_AT_abstract_origin:
3046 case DW_AT_sibling:
3047 break;
3048 }
3049 }
3050 }
3051
3052 Type *element_type = ResolveTypeUID(type_die_offset);
3053
3054 if (element_type)
3055 {
3056 std::vector<uint64_t> element_orders;
3057 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00003058 // We have an array that claims to have no members, lets give it at least one member...
3059 if (element_orders.empty())
3060 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003061 if (byte_stride == 0 && bit_stride == 0)
3062 byte_stride = element_type->GetByteSize();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003063 clang_type_t array_element_type = element_type->GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003064 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3065 uint64_t num_elements = 0;
3066 std::vector<uint64_t>::const_reverse_iterator pos;
3067 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3068 for (pos = element_orders.rbegin(); pos != end; ++pos)
3069 {
3070 num_elements = *pos;
3071 clang_type = type_list->GetClangASTContext().CreateArrayType (array_element_type, num_elements, num_elements * array_element_bit_stride);
3072 array_element_type = clang_type;
3073 array_element_bit_stride = array_element_bit_stride * num_elements;
3074 }
3075 ConstString empty_name;
Greg Clayton4957bf62010-09-30 21:49:03 +00003076 type_sp.reset( new Type(die->GetOffset(), this, empty_name, array_element_bit_stride / 8, NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, clang_type, false));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003077 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003078 }
3079 }
3080 }
3081 break;
3082
Greg Clayton9b81a312010-06-12 01:20:30 +00003083 case DW_TAG_ptr_to_member_type:
3084 {
3085 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3086 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3087
Greg Claytond88d7592010-09-15 08:33:30 +00003088 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00003089
3090 if (num_attributes > 0) {
3091 uint32_t i;
3092 for (i=0; i<num_attributes; ++i)
3093 {
3094 attr = attributes.AttributeAtIndex(i);
3095 DWARFFormValue form_value;
3096 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3097 {
3098 switch (attr)
3099 {
3100 case DW_AT_type:
3101 type_die_offset = form_value.Reference(dwarf_cu); break;
3102 case DW_AT_containing_type:
3103 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3104 }
3105 }
3106 }
3107
3108 Type *pointee_type = ResolveTypeUID(type_die_offset);
3109 Type *class_type = ResolveTypeUID(containing_type_die_offset);
3110
Greg Clayton1be10fc2010-09-29 01:12:09 +00003111 clang_type_t pointee_clang_type = pointee_type->GetClangType();
3112 clang_type_t class_clang_type = class_type->GetClangType();
Greg Clayton9b81a312010-06-12 01:20:30 +00003113
Greg Claytonb1320972010-07-14 00:18:15 +00003114 clang_type = type_list->GetClangASTContext().CreateMemberPointerType(pointee_clang_type, class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00003115
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003116 size_t byte_size = ClangASTType::GetClangTypeBitWidth (type_list->GetClangASTContext().getASTContext(), clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00003117
Greg Clayton4957bf62010-09-30 21:49:03 +00003118 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, NULL, clang_type, false));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003119 m_die_to_type[die] = type_sp.get();
Greg Clayton9b81a312010-06-12 01:20:30 +00003120 }
3121
3122 break;
3123 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003124 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00003125 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003126 break;
3127 }
3128
3129 if (type_sp.get())
3130 {
3131 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3132 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3133
3134 SymbolContextScope * symbol_context_scope = NULL;
3135 if (sc_parent_tag == DW_TAG_compile_unit)
3136 {
3137 symbol_context_scope = sc.comp_unit;
3138 }
3139 else if (sc.function != NULL)
3140 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003141 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003142 if (symbol_context_scope == NULL)
3143 symbol_context_scope = sc.function;
3144 }
3145
3146 if (symbol_context_scope != NULL)
3147 {
3148 type_sp->SetSymbolContextScope(symbol_context_scope);
3149 }
3150
3151// if (udt_sp.get())
3152// {
3153// if (is_forward_declaration)
3154// udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
3155// type_sp->SetUserDefinedType(udt_sp);
3156// }
3157
3158 if (type_sp.unique())
3159 {
3160 // We are ready to put this type into the uniqued list up at the module level
3161 TypeSP uniqued_type_sp(m_obj_file->GetModule()->GetTypeList()->InsertUnique(type_sp));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003162 type_sp = uniqued_type_sp;
Greg Clayton594e5ed2010-09-27 21:07:38 +00003163 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003164 }
3165 }
3166 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00003167 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003168 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00003169 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003170 }
3171 }
3172 return type_sp;
3173}
3174
3175size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00003176SymbolFileDWARF::ParseTypes
3177(
3178 const SymbolContext& sc,
3179 DWARFCompileUnit* dwarf_cu,
3180 const DWARFDebugInfoEntry *die,
3181 bool parse_siblings,
3182 bool parse_children
3183)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003184{
3185 size_t types_added = 0;
3186 while (die != NULL)
3187 {
3188 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003189 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003190 {
3191 if (type_is_new)
3192 ++types_added;
3193 }
3194
3195 if (parse_children && die->HasChildren())
3196 {
3197 if (die->Tag() == DW_TAG_subprogram)
3198 {
3199 SymbolContext child_sc(sc);
3200 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3201 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3202 }
3203 else
3204 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3205 }
3206
3207 if (parse_siblings)
3208 die = die->GetSibling();
3209 else
3210 die = NULL;
3211 }
3212 return types_added;
3213}
3214
3215
3216size_t
3217SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3218{
3219 assert(sc.comp_unit && sc.function);
3220 size_t functions_added = 0;
3221 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3222 if (dwarf_cu)
3223 {
3224 dw_offset_t function_die_offset = sc.function->GetID();
3225 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3226 if (function_die)
3227 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003228 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003229 }
3230 }
3231
3232 return functions_added;
3233}
3234
3235
3236size_t
3237SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3238{
3239 // At least a compile unit must be valid
3240 assert(sc.comp_unit);
3241 size_t types_added = 0;
3242 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3243 if (dwarf_cu)
3244 {
3245 if (sc.function)
3246 {
3247 dw_offset_t function_die_offset = sc.function->GetID();
3248 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3249 if (func_die && func_die->HasChildren())
3250 {
3251 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3252 }
3253 }
3254 else
3255 {
3256 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3257 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3258 {
3259 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3260 }
3261 }
3262 }
3263
3264 return types_added;
3265}
3266
3267size_t
3268SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3269{
3270 if (sc.comp_unit != NULL)
3271 {
3272 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3273
3274 if (dwarf_cu == NULL)
3275 return 0;
3276
3277 if (sc.function)
3278 {
3279 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00003280
3281 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
3282 assert (func_lo_pc != DW_INVALID_ADDRESS);
3283
3284 return ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003285 }
3286 else if (sc.comp_unit)
3287 {
3288 uint32_t vars_added = 0;
3289 VariableListSP variables (sc.comp_unit->GetVariableList(false));
3290
3291 if (variables.get() == NULL)
3292 {
3293 variables.reset(new VariableList());
3294 sc.comp_unit->SetVariableList(variables);
3295
3296 // Index if we already haven't to make sure the compile units
3297 // get indexed and make their global DIE index list
3298 if (!m_indexed)
3299 Index ();
3300
Greg Claytonc685f8e2010-09-15 04:15:46 +00003301
3302 std::vector<NameToDIE::Info> global_die_info_array;
3303 const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (sc.comp_unit->GetID(), global_die_info_array);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003304 for (size_t idx=0; idx<num_globals; ++idx)
3305 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00003306 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetDIEAtIndexUnchecked(global_die_info_array[idx].die_idx), LLDB_INVALID_ADDRESS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003307 if (var_sp)
3308 {
3309 variables->AddVariable(var_sp);
3310 ++vars_added;
3311 }
3312 }
3313 }
3314 return vars_added;
3315 }
3316 }
3317 return 0;
3318}
3319
3320
3321VariableSP
3322SymbolFileDWARF::ParseVariableDIE
3323(
3324 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003325 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00003326 const DWARFDebugInfoEntry *die,
3327 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003328)
3329{
3330
3331 VariableSP var_sp;
3332
3333 const dw_tag_t tag = die->Tag();
3334 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003335 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003336 if (num_attributes > 0)
3337 {
3338 const char *name = NULL;
Greg Claytona134cc12010-09-13 02:37:44 +00003339 const char *mangled = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003340 Declaration decl;
3341 uint32_t i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003342 Type *var_type = NULL;
3343 DWARFExpression location;
3344 bool is_external = false;
3345 bool is_artificial = false;
Sean Callananc7fbf732010-08-06 00:32:49 +00003346 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003347
3348 for (i=0; i<num_attributes; ++i)
3349 {
3350 dw_attr_t attr = attributes.AttributeAtIndex(i);
3351 DWARFFormValue form_value;
3352 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3353 {
3354 switch (attr)
3355 {
3356 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3357 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3358 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3359 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Claytona134cc12010-09-13 02:37:44 +00003360 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton594e5ed2010-09-27 21:07:38 +00003361 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003362 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
3363 case DW_AT_location:
3364 {
3365 if (form_value.BlockData())
3366 {
3367 const DataExtractor& debug_info_data = get_debug_info_data();
3368
3369 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3370 uint32_t block_length = form_value.Unsigned();
Greg Clayton016a95e2010-09-14 02:20:48 +00003371 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003372 }
3373 else
3374 {
3375 const DataExtractor& debug_loc_data = get_debug_loc_data();
3376 const dw_offset_t debug_loc_offset = form_value.Unsigned();
3377
3378 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
3379 if (loc_list_length > 0)
3380 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003381 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
3382 assert (func_low_pc != LLDB_INVALID_ADDRESS);
3383 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003384 }
3385 }
3386 }
3387 break;
3388
3389 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003390 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003391 case DW_AT_const_value:
3392 case DW_AT_declaration:
3393 case DW_AT_description:
3394 case DW_AT_endianity:
3395 case DW_AT_segment:
3396 case DW_AT_start_scope:
3397 case DW_AT_visibility:
3398 default:
3399 case DW_AT_abstract_origin:
3400 case DW_AT_sibling:
3401 case DW_AT_specification:
3402 break;
3403 }
3404 }
3405 }
3406
3407 if (location.IsValid())
3408 {
3409 assert(var_type != DIE_IS_BEING_PARSED);
3410
Greg Claytona134cc12010-09-13 02:37:44 +00003411 ConstString var_name;
3412 if (mangled)
3413 {
3414 Mangled mangled_var_name (mangled, true);
3415 var_name = mangled_var_name.GetDemangledName();
3416 }
3417
3418 if (!var_name && name)
3419 {
3420 var_name.SetCString(name);
3421 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003422
3423 ValueType scope = eValueTypeInvalid;
3424
3425 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3426 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3427
3428 if (tag == DW_TAG_formal_parameter)
3429 scope = eValueTypeVariableArgument;
3430 else if (is_external || parent_tag == DW_TAG_compile_unit)
3431 scope = eValueTypeVariableGlobal;
3432 else
3433 scope = eValueTypeVariableLocal;
3434
3435 SymbolContextScope * symbol_context_scope = NULL;
3436 if (parent_tag == DW_TAG_compile_unit)
3437 {
3438 symbol_context_scope = sc.comp_unit;
3439 }
3440 else if (sc.function != NULL)
3441 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003442 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003443 if (symbol_context_scope == NULL)
3444 symbol_context_scope = sc.function;
3445 }
3446
3447 assert(symbol_context_scope != NULL);
3448 var_sp.reset (new Variable(die->GetOffset(),
3449 var_name,
3450 var_type,
3451 scope,
3452 symbol_context_scope,
3453 &decl,
3454 location,
3455 is_external,
3456 is_artificial));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003457
3458 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003459 }
3460 }
3461 return var_sp;
3462}
3463
3464size_t
3465SymbolFileDWARF::ParseVariables
3466(
3467 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003468 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00003469 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003470 const DWARFDebugInfoEntry *orig_die,
3471 bool parse_siblings,
3472 bool parse_children,
3473 VariableList* cc_variable_list
3474)
3475{
3476 if (orig_die == NULL)
3477 return 0;
3478
3479 size_t vars_added = 0;
3480 const DWARFDebugInfoEntry *die = orig_die;
3481 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
3482 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3483 VariableListSP variables;
3484 switch (parent_tag)
3485 {
3486 case DW_TAG_compile_unit:
3487 if (sc.comp_unit != NULL)
3488 {
3489 variables = sc.comp_unit->GetVariableList(false);
3490 if (variables.get() == NULL)
3491 {
3492 variables.reset(new VariableList());
3493 sc.comp_unit->SetVariableList(variables);
3494 }
3495 }
3496 else
3497 {
3498 assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
3499 vars_added = 0;
3500 }
3501 break;
3502
3503 case DW_TAG_subprogram:
3504 case DW_TAG_inlined_subroutine:
3505 case DW_TAG_lexical_block:
3506 if (sc.function != NULL)
3507 {
3508 // Check to see if we already have parsed the variables for the given scope
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003509
3510 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
3511 assert (block != NULL);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003512 variables = block->GetVariableList(false, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003513 if (variables.get() == NULL)
3514 {
3515 variables.reset(new VariableList());
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003516 block->SetVariableList(variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003517 }
3518 }
3519 else
3520 {
3521 assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
3522 vars_added = 0;
3523 }
3524 break;
3525
3526 default:
3527 assert(!"Didn't find appropriate parent DIE for variable list...");
3528 break;
3529 }
3530
3531 // We need to have a variable list at this point that we can add variables to
3532 assert(variables.get());
3533
3534 while (die != NULL)
3535 {
3536 dw_tag_t tag = die->Tag();
3537
3538 // Check to see if we have already parsed this variable or constant?
Greg Clayton594e5ed2010-09-27 21:07:38 +00003539 if (m_die_to_variable_sp[die].get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003540 {
3541 // We haven't already parsed it, lets do that now.
3542 if ((tag == DW_TAG_variable) ||
3543 (tag == DW_TAG_constant) ||
3544 (tag == DW_TAG_formal_parameter && sc.function))
3545 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003546 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003547 if (var_sp)
3548 {
3549 variables->AddVariable(var_sp);
3550 ++vars_added;
3551 }
3552 }
3553 }
3554
3555 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
3556
3557 if (!skip_children && parse_children && die->HasChildren())
3558 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003559 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003560 //vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), parse_siblings, parse_children);
3561 }
3562
3563 if (parse_siblings)
3564 die = die->GetSibling();
3565 else
3566 die = NULL;
3567 }
3568
3569 if (cc_variable_list)
3570 {
3571 cc_variable_list->AddVariables(variables.get());
3572 }
3573
3574 return vars_added;
3575}
3576
3577//------------------------------------------------------------------
3578// PluginInterface protocol
3579//------------------------------------------------------------------
3580const char *
3581SymbolFileDWARF::GetPluginName()
3582{
3583 return "SymbolFileDWARF";
3584}
3585
3586const char *
3587SymbolFileDWARF::GetShortPluginName()
3588{
3589 return GetPluginNameStatic();
3590}
3591
3592uint32_t
3593SymbolFileDWARF::GetPluginVersion()
3594{
3595 return 1;
3596}
3597
3598void
3599SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
3600{
3601}
3602
3603Error
3604SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
3605{
3606 Error error;
3607 error.SetErrorString("No plug-in command are currently supported.");
3608 return error;
3609}
3610
3611Log *
3612SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
3613{
3614 return NULL;
3615}
3616