blob: 31e313da63730e4634b9e1d0cd410f3708ea981e [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;
2447 Type::EncodingUIDType encoding_uid_type = Type::eIsTypeWithUID;
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()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002511 encoding_uid_type = Type::ePointerToTypeWithUID;
2512 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()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002517 encoding_uid_type = Type::eLValueReferenceToTypeWithUID;
2518 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()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002523 encoding_uid_type = Type::eTypedefToTypeWithUID;
2524 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()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002529 encoding_uid_type = Type::eIsConstTypeWithUID; //ClangASTContext::AddConstModifier (clang_type);
2530 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()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002535 encoding_uid_type = Type::eIsRestrictTypeWithUID; //ClangASTContext::AddRestrictModifier (clang_type);
2536 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()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002541 encoding_uid_type = Type::eIsVolatileTypeWithUID; //ClangASTContext::AddVolatileModifier (clang_type);
2542 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
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002566 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, encoding_uid_type, &decl, clang_type));
2567
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);
2682 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
2683
Greg Clayton594e5ed2010-09-27 21:07:38 +00002684 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002685
Greg Clayton1be10fc2010-09-29 01:12:09 +00002686 // Leave this as a forward declaration until we need
2687 // to know the details of the type. lldb_private::Type
2688 // will automatically call the SymbolFile virtual function
2689 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
2690 // When the definition needs to be defined.
2691 if (clang_type_was_created)
2692 {
2693 m_forward_decl_die_to_clang_type[die] = clang_type;
2694 m_forward_decl_clang_type_to_die[clang_type] = die;
2695 }
2696
2697#if 0
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002698 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
2699 if (die->HasChildren())
2700 {
2701 std::vector<clang::CXXBaseSpecifier *> base_classes;
2702 std::vector<int> member_accessibilities;
2703 bool is_a_class = false;
Greg Clayton9e409562010-07-28 02:04:09 +00002704 ParseChildMembers (sc,
Greg Clayton9e409562010-07-28 02:04:09 +00002705 dwarf_cu,
2706 die,
2707 clang_type,
2708 class_language,
2709 base_classes,
2710 member_accessibilities,
2711 default_accessibility,
2712 is_a_class);
2713
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002714 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
2715 // need to tell the clang type it is actually a class.
Greg Clayton9e409562010-07-28 02:04:09 +00002716 if (class_language != eLanguageTypeObjC)
2717 {
2718 if (is_a_class && tag_decl_kind != clang::TTK_Class)
2719 type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class);
2720 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002721
2722 // Since DW_TAG_structure_type gets used for both classes
2723 // and structures, we may need to set any DW_TAG_member
2724 // fields to have a "private" access if none was specified.
2725 // When we parsed the child members we tracked that actual
2726 // accessibility value for each DW_TAG_member in the
2727 // "member_accessibilities" array. If the value for the
2728 // member is zero, then it was set to the "default_accessibility"
2729 // which for structs was "public". Below we correct this
2730 // by setting any fields to "private" that weren't correctly
2731 // set.
2732 if (is_a_class && !member_accessibilities.empty())
2733 {
2734 // This is a class and all members that didn't have
2735 // their access specified are private.
Sean Callananc7fbf732010-08-06 00:32:49 +00002736 type_list->GetClangASTContext().SetDefaultAccessForRecordFields (clang_type, eAccessPrivate, &member_accessibilities.front(), member_accessibilities.size());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002737 }
2738
2739 if (!base_classes.empty())
2740 {
Greg Clayton471b31c2010-07-20 22:52:08 +00002741 type_list->GetClangASTContext().SetBaseClassesForClassType (clang_type, &base_classes.front(), base_classes.size());
2742
2743 // Clang will copy each CXXBaseSpecifier in "base_classes"
2744 // so we have to free them all.
2745 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(), base_classes.size());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002746 }
Greg Clayton0b42ac32010-07-02 01:29:13 +00002747
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002748 }
2749 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00002750#endif // #if 0
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002751 }
2752 break;
2753
2754 case DW_TAG_enumeration_type:
2755 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002756 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002757 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002758
2759 size_t byte_size = 0;
2760 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
2761 Declaration decl;
2762
Greg Claytond88d7592010-09-15 08:33:30 +00002763 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002764 if (num_attributes > 0)
2765 {
2766 uint32_t i;
2767
2768 for (i=0; i<num_attributes; ++i)
2769 {
2770 attr = attributes.AttributeAtIndex(i);
2771 DWARFFormValue form_value;
2772 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2773 {
2774 switch (attr)
2775 {
2776 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2777 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2778 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2779 case DW_AT_name:
2780 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2781 type_name_dbstr.SetCString(type_name_cstr);
2782 break;
2783 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2784 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00002785 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002786 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
2787 case DW_AT_allocated:
2788 case DW_AT_associated:
2789 case DW_AT_bit_stride:
2790 case DW_AT_byte_stride:
2791 case DW_AT_data_location:
2792 case DW_AT_description:
2793 case DW_AT_start_scope:
2794 case DW_AT_visibility:
2795 case DW_AT_specification:
2796 case DW_AT_abstract_origin:
2797 case DW_AT_sibling:
2798 break;
2799 }
2800 }
2801 }
2802
Greg Clayton1be10fc2010-09-29 01:12:09 +00002803 clang_type_t enumerator_clang_type = NULL;
2804 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
2805 if (clang_type == NULL)
2806 {
2807 enumerator_clang_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, DW_ATE_signed, byte_size * 8);
2808 clang_type = type_list->GetClangASTContext().CreateEnumerationType(decl, type_name_cstr, enumerator_clang_type);
2809 }
2810 else
2811 {
2812 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
2813 assert (enumerator_clang_type != NULL);
2814 }
2815
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002816 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
2817 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, Type::eIsTypeWithUID, &decl, clang_type));
2818
Greg Clayton594e5ed2010-09-27 21:07:38 +00002819 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002820
Greg Clayton1be10fc2010-09-29 01:12:09 +00002821 // Leave this as a forward declaration until we need
2822 // to know the details of the type. lldb_private::Type
2823 // will automatically call the SymbolFile virtual function
2824 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
2825 // When the definition needs to be defined.
2826 m_forward_decl_die_to_clang_type[die] = clang_type;
2827 m_forward_decl_clang_type_to_die[clang_type] = die;
2828
2829#if 0
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002830 if (die->HasChildren())
2831 {
2832 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00002833 ParseChildEnumerators(sc, enumerator_clang_type, byte_size, dwarf_cu, die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002834 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
2835 }
Greg Clayton1be10fc2010-09-29 01:12:09 +00002836#endif // #if 0
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002837 }
2838 }
2839 break;
2840
Jim Inghamb0be4422010-08-12 01:20:14 +00002841 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002842 case DW_TAG_subprogram:
2843 case DW_TAG_subroutine_type:
2844 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002845 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002846 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002847
2848 const char *mangled = NULL;
2849 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
2850 Declaration decl;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002851 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002852 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00002853 bool is_static = false;
2854 bool is_virtual = false;
2855
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002856 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00002857 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002858
2859
Greg Claytond88d7592010-09-15 08:33:30 +00002860 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002861 if (num_attributes > 0)
2862 {
2863 uint32_t i;
2864 for (i=0; i<num_attributes; ++i)
2865 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002866 const dw_attr_t attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002867 DWARFFormValue form_value;
2868 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2869 {
2870 switch (attr)
2871 {
2872 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2873 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2874 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2875 case DW_AT_name:
2876 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2877 type_name_dbstr.SetCString(type_name_cstr);
2878 break;
2879
2880 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
2881 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00002882 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002883 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00002884 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
2885 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002886 case DW_AT_external:
2887 if (form_value.Unsigned())
2888 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00002889 if (storage == clang::SC_None)
2890 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002891 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00002892 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002893 }
2894 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002895
2896 case DW_AT_allocated:
2897 case DW_AT_associated:
2898 case DW_AT_address_class:
2899 case DW_AT_artificial:
2900 case DW_AT_calling_convention:
2901 case DW_AT_data_location:
2902 case DW_AT_elemental:
2903 case DW_AT_entry_pc:
2904 case DW_AT_explicit:
2905 case DW_AT_frame_base:
2906 case DW_AT_high_pc:
2907 case DW_AT_low_pc:
2908 case DW_AT_object_pointer:
2909 case DW_AT_prototyped:
2910 case DW_AT_pure:
2911 case DW_AT_ranges:
2912 case DW_AT_recursive:
2913 case DW_AT_return_addr:
2914 case DW_AT_segment:
2915 case DW_AT_specification:
2916 case DW_AT_start_scope:
2917 case DW_AT_static_link:
2918 case DW_AT_trampoline:
2919 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002920 case DW_AT_vtable_elem_location:
2921 case DW_AT_abstract_origin:
2922 case DW_AT_description:
2923 case DW_AT_sibling:
2924 break;
2925 }
2926 }
2927 }
2928
Greg Clayton1be10fc2010-09-29 01:12:09 +00002929 clang_type_t return_clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002930 Type *func_type = ResolveTypeUID(type_die_offset);
2931 if (func_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00002932 return_clang_type = func_type->GetClangType(true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002933 else
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002934 return_clang_type = type_list->GetClangASTContext().GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002935
Greg Clayton1be10fc2010-09-29 01:12:09 +00002936 std::vector<clang_type_t> function_param_types;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002937 std::vector<clang::ParmVarDecl*> function_param_decls;
2938
2939 // Parse the function children for the parameters
Greg Clayton0fffff52010-09-24 05:15:53 +00002940 bool skip_artificial = true;
2941 ParseChildParameters (sc, type_sp, dwarf_cu, die, skip_artificial, type_list, function_param_types, function_param_decls);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002942
Greg Clayton0fffff52010-09-24 05:15:53 +00002943 // clang_type will get the function prototype clang type after this call
Greg Claytona51ed9b2010-09-23 01:09:21 +00002944 clang_type = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), is_variadic, type_quals);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002945 if (type_name_cstr)
2946 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002947 bool type_handled = false;
2948 const DWARFDebugInfoEntry *parent_die = die->GetParent();
2949 if (tag == DW_TAG_subprogram)
2950 {
2951 if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+'))
2952 {
2953 // We need to find the DW_TAG_class_type or
2954 // DW_TAG_struct_type by name so we can add this
2955 // as a member function of the class.
2956 const char *class_name_start = type_name_cstr + 2;
2957 const char *class_name_end = ::strchr (class_name_start, ' ');
2958 SymbolContext empty_sc;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002959 clang_type_t class_opaque_type = NULL;
Greg Clayton0fffff52010-09-24 05:15:53 +00002960 if (class_name_start < class_name_end)
2961 {
2962 ConstString class_name (class_name_start, class_name_end - class_name_start);
2963 TypeList types;
2964 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
2965 if (match_count > 0)
2966 {
2967 for (uint32_t i=0; i<match_count; ++i)
2968 {
2969 Type *type = types.GetTypeAtIndex (i).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00002970 if (ClangASTContext::IsObjCClassType (type->GetClangType()))
Greg Clayton0fffff52010-09-24 05:15:53 +00002971 {
Greg Clayton1be10fc2010-09-29 01:12:09 +00002972 class_opaque_type = type->GetClangType();
Greg Clayton0fffff52010-09-24 05:15:53 +00002973 break;
2974 }
2975 }
2976 }
2977 }
2978
2979 if (class_opaque_type)
2980 {
2981 clang::ObjCMethodDecl *objc_method_decl;
2982 objc_method_decl = type_list->GetClangASTContext().AddMethodToObjCObjectType (class_opaque_type,
2983 type_name_cstr,
2984 clang_type,
2985 accessibility);
2986 type_handled = objc_method_decl != NULL;
2987 }
2988 }
2989 else if (parent_die->Tag() == DW_TAG_class_type ||
2990 parent_die->Tag() == DW_TAG_structure_type)
2991 {
2992 // Look at the parent of this DIE and see if is is
2993 // a class or struct and see if this is actually a
2994 // C++ method
2995 Type *class_type = ResolveType (dwarf_cu, parent_die);
2996 if (class_type)
2997 {
Greg Clayton1be10fc2010-09-29 01:12:09 +00002998 clang_type_t class_opaque_type = class_type->GetClangType (true);
Greg Clayton0fffff52010-09-24 05:15:53 +00002999 if (ClangASTContext::IsCXXClassType (class_opaque_type))
3000 {
3001 clang::CXXMethodDecl *cxx_method_decl;
3002 cxx_method_decl = type_list->GetClangASTContext().AddMethodToCXXRecordType (class_opaque_type,
3003 type_name_cstr,
3004 clang_type,
3005 accessibility,
3006 is_virtual,
3007 is_static,
3008 is_inline);
3009 type_handled = cxx_method_decl != NULL;
3010 }
3011 }
3012 }
3013 }
3014
3015 if (!type_handled)
3016 {
3017 // We just have a function that isn't part of a class
3018 clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline);
3019
3020 // Add the decl to our DIE to decl context map
3021 assert (function_decl);
3022 m_die_to_decl_ctx[die] = function_decl;
3023 if (!function_param_decls.empty())
3024 type_list->GetClangASTContext().SetFunctionParameters (function_decl, &function_param_decls.front(), function_param_decls.size());
3025 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003026 }
3027 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, 0, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
3028
Greg Clayton594e5ed2010-09-27 21:07:38 +00003029 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003030 assert(type_sp.get());
3031 }
3032 }
3033 break;
3034
3035 case DW_TAG_array_type:
3036 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003037 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003038 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003039
3040 size_t byte_size = 0;
3041 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
3042 Declaration decl;
3043 int64_t first_index = 0;
3044 uint32_t byte_stride = 0;
3045 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00003046 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003047
3048 if (num_attributes > 0)
3049 {
3050 uint32_t i;
3051 for (i=0; i<num_attributes; ++i)
3052 {
3053 attr = attributes.AttributeAtIndex(i);
3054 DWARFFormValue form_value;
3055 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3056 {
3057 switch (attr)
3058 {
3059 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3060 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3061 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3062 case DW_AT_name:
3063 type_name_cstr = form_value.AsCString(&get_debug_str_data());
3064 type_name_dbstr.SetCString(type_name_cstr);
3065 break;
3066
3067 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
3068 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3069 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3070 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003071 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003072 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
3073 case DW_AT_allocated:
3074 case DW_AT_associated:
3075 case DW_AT_data_location:
3076 case DW_AT_description:
3077 case DW_AT_ordering:
3078 case DW_AT_start_scope:
3079 case DW_AT_visibility:
3080 case DW_AT_specification:
3081 case DW_AT_abstract_origin:
3082 case DW_AT_sibling:
3083 break;
3084 }
3085 }
3086 }
3087
3088 Type *element_type = ResolveTypeUID(type_die_offset);
3089
3090 if (element_type)
3091 {
3092 std::vector<uint64_t> element_orders;
3093 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00003094 // We have an array that claims to have no members, lets give it at least one member...
3095 if (element_orders.empty())
3096 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003097 if (byte_stride == 0 && bit_stride == 0)
3098 byte_stride = element_type->GetByteSize();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003099 clang_type_t array_element_type = element_type->GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003100 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3101 uint64_t num_elements = 0;
3102 std::vector<uint64_t>::const_reverse_iterator pos;
3103 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3104 for (pos = element_orders.rbegin(); pos != end; ++pos)
3105 {
3106 num_elements = *pos;
3107 clang_type = type_list->GetClangASTContext().CreateArrayType (array_element_type, num_elements, num_elements * array_element_bit_stride);
3108 array_element_type = clang_type;
3109 array_element_bit_stride = array_element_bit_stride * num_elements;
3110 }
3111 ConstString empty_name;
3112 type_sp.reset( new Type(die->GetOffset(), this, empty_name, array_element_bit_stride / 8, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003113 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003114 }
3115 }
3116 }
3117 break;
3118
Greg Clayton9b81a312010-06-12 01:20:30 +00003119 case DW_TAG_ptr_to_member_type:
3120 {
3121 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3122 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3123
Greg Claytond88d7592010-09-15 08:33:30 +00003124 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00003125
3126 if (num_attributes > 0) {
3127 uint32_t i;
3128 for (i=0; i<num_attributes; ++i)
3129 {
3130 attr = attributes.AttributeAtIndex(i);
3131 DWARFFormValue form_value;
3132 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3133 {
3134 switch (attr)
3135 {
3136 case DW_AT_type:
3137 type_die_offset = form_value.Reference(dwarf_cu); break;
3138 case DW_AT_containing_type:
3139 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3140 }
3141 }
3142 }
3143
3144 Type *pointee_type = ResolveTypeUID(type_die_offset);
3145 Type *class_type = ResolveTypeUID(containing_type_die_offset);
3146
Greg Clayton1be10fc2010-09-29 01:12:09 +00003147 clang_type_t pointee_clang_type = pointee_type->GetClangType();
3148 clang_type_t class_clang_type = class_type->GetClangType();
Greg Clayton9b81a312010-06-12 01:20:30 +00003149
Greg Claytonb1320972010-07-14 00:18:15 +00003150 clang_type = type_list->GetClangASTContext().CreateMemberPointerType(pointee_clang_type, class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00003151
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003152 size_t byte_size = ClangASTType::GetClangTypeBitWidth (type_list->GetClangASTContext().getASTContext(), clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00003153
3154 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, NULL, clang_type));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003155 m_die_to_type[die] = type_sp.get();
Greg Clayton9b81a312010-06-12 01:20:30 +00003156 }
3157
3158 break;
3159 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003160 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00003161 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003162 break;
3163 }
3164
3165 if (type_sp.get())
3166 {
3167 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3168 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3169
3170 SymbolContextScope * symbol_context_scope = NULL;
3171 if (sc_parent_tag == DW_TAG_compile_unit)
3172 {
3173 symbol_context_scope = sc.comp_unit;
3174 }
3175 else if (sc.function != NULL)
3176 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003177 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003178 if (symbol_context_scope == NULL)
3179 symbol_context_scope = sc.function;
3180 }
3181
3182 if (symbol_context_scope != NULL)
3183 {
3184 type_sp->SetSymbolContextScope(symbol_context_scope);
3185 }
3186
3187// if (udt_sp.get())
3188// {
3189// if (is_forward_declaration)
3190// udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
3191// type_sp->SetUserDefinedType(udt_sp);
3192// }
3193
3194 if (type_sp.unique())
3195 {
3196 // We are ready to put this type into the uniqued list up at the module level
3197 TypeSP uniqued_type_sp(m_obj_file->GetModule()->GetTypeList()->InsertUnique(type_sp));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003198 type_sp = uniqued_type_sp;
Greg Clayton594e5ed2010-09-27 21:07:38 +00003199 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003200 }
3201 }
3202 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00003203 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003204 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00003205 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003206 }
3207 }
3208 return type_sp;
3209}
3210
3211size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00003212SymbolFileDWARF::ParseTypes
3213(
3214 const SymbolContext& sc,
3215 DWARFCompileUnit* dwarf_cu,
3216 const DWARFDebugInfoEntry *die,
3217 bool parse_siblings,
3218 bool parse_children
3219)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003220{
3221 size_t types_added = 0;
3222 while (die != NULL)
3223 {
3224 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003225 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003226 {
3227 if (type_is_new)
3228 ++types_added;
3229 }
3230
3231 if (parse_children && die->HasChildren())
3232 {
3233 if (die->Tag() == DW_TAG_subprogram)
3234 {
3235 SymbolContext child_sc(sc);
3236 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3237 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3238 }
3239 else
3240 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3241 }
3242
3243 if (parse_siblings)
3244 die = die->GetSibling();
3245 else
3246 die = NULL;
3247 }
3248 return types_added;
3249}
3250
3251
3252size_t
3253SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3254{
3255 assert(sc.comp_unit && sc.function);
3256 size_t functions_added = 0;
3257 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3258 if (dwarf_cu)
3259 {
3260 dw_offset_t function_die_offset = sc.function->GetID();
3261 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3262 if (function_die)
3263 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003264 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003265 }
3266 }
3267
3268 return functions_added;
3269}
3270
3271
3272size_t
3273SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3274{
3275 // At least a compile unit must be valid
3276 assert(sc.comp_unit);
3277 size_t types_added = 0;
3278 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3279 if (dwarf_cu)
3280 {
3281 if (sc.function)
3282 {
3283 dw_offset_t function_die_offset = sc.function->GetID();
3284 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3285 if (func_die && func_die->HasChildren())
3286 {
3287 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3288 }
3289 }
3290 else
3291 {
3292 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3293 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3294 {
3295 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3296 }
3297 }
3298 }
3299
3300 return types_added;
3301}
3302
3303size_t
3304SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3305{
3306 if (sc.comp_unit != NULL)
3307 {
3308 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3309
3310 if (dwarf_cu == NULL)
3311 return 0;
3312
3313 if (sc.function)
3314 {
3315 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00003316
3317 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
3318 assert (func_lo_pc != DW_INVALID_ADDRESS);
3319
3320 return ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003321 }
3322 else if (sc.comp_unit)
3323 {
3324 uint32_t vars_added = 0;
3325 VariableListSP variables (sc.comp_unit->GetVariableList(false));
3326
3327 if (variables.get() == NULL)
3328 {
3329 variables.reset(new VariableList());
3330 sc.comp_unit->SetVariableList(variables);
3331
3332 // Index if we already haven't to make sure the compile units
3333 // get indexed and make their global DIE index list
3334 if (!m_indexed)
3335 Index ();
3336
Greg Claytonc685f8e2010-09-15 04:15:46 +00003337
3338 std::vector<NameToDIE::Info> global_die_info_array;
3339 const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (sc.comp_unit->GetID(), global_die_info_array);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003340 for (size_t idx=0; idx<num_globals; ++idx)
3341 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00003342 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 +00003343 if (var_sp)
3344 {
3345 variables->AddVariable(var_sp);
3346 ++vars_added;
3347 }
3348 }
3349 }
3350 return vars_added;
3351 }
3352 }
3353 return 0;
3354}
3355
3356
3357VariableSP
3358SymbolFileDWARF::ParseVariableDIE
3359(
3360 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003361 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00003362 const DWARFDebugInfoEntry *die,
3363 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003364)
3365{
3366
3367 VariableSP var_sp;
3368
3369 const dw_tag_t tag = die->Tag();
3370 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003371 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003372 if (num_attributes > 0)
3373 {
3374 const char *name = NULL;
Greg Claytona134cc12010-09-13 02:37:44 +00003375 const char *mangled = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003376 Declaration decl;
3377 uint32_t i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003378 Type *var_type = NULL;
3379 DWARFExpression location;
3380 bool is_external = false;
3381 bool is_artificial = false;
Sean Callananc7fbf732010-08-06 00:32:49 +00003382 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003383
3384 for (i=0; i<num_attributes; ++i)
3385 {
3386 dw_attr_t attr = attributes.AttributeAtIndex(i);
3387 DWARFFormValue form_value;
3388 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3389 {
3390 switch (attr)
3391 {
3392 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3393 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3394 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3395 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Claytona134cc12010-09-13 02:37:44 +00003396 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton594e5ed2010-09-27 21:07:38 +00003397 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003398 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
3399 case DW_AT_location:
3400 {
3401 if (form_value.BlockData())
3402 {
3403 const DataExtractor& debug_info_data = get_debug_info_data();
3404
3405 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3406 uint32_t block_length = form_value.Unsigned();
Greg Clayton016a95e2010-09-14 02:20:48 +00003407 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003408 }
3409 else
3410 {
3411 const DataExtractor& debug_loc_data = get_debug_loc_data();
3412 const dw_offset_t debug_loc_offset = form_value.Unsigned();
3413
3414 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
3415 if (loc_list_length > 0)
3416 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003417 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
3418 assert (func_low_pc != LLDB_INVALID_ADDRESS);
3419 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003420 }
3421 }
3422 }
3423 break;
3424
3425 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003426 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003427 case DW_AT_const_value:
3428 case DW_AT_declaration:
3429 case DW_AT_description:
3430 case DW_AT_endianity:
3431 case DW_AT_segment:
3432 case DW_AT_start_scope:
3433 case DW_AT_visibility:
3434 default:
3435 case DW_AT_abstract_origin:
3436 case DW_AT_sibling:
3437 case DW_AT_specification:
3438 break;
3439 }
3440 }
3441 }
3442
3443 if (location.IsValid())
3444 {
3445 assert(var_type != DIE_IS_BEING_PARSED);
3446
Greg Claytona134cc12010-09-13 02:37:44 +00003447 ConstString var_name;
3448 if (mangled)
3449 {
3450 Mangled mangled_var_name (mangled, true);
3451 var_name = mangled_var_name.GetDemangledName();
3452 }
3453
3454 if (!var_name && name)
3455 {
3456 var_name.SetCString(name);
3457 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003458
3459 ValueType scope = eValueTypeInvalid;
3460
3461 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3462 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3463
3464 if (tag == DW_TAG_formal_parameter)
3465 scope = eValueTypeVariableArgument;
3466 else if (is_external || parent_tag == DW_TAG_compile_unit)
3467 scope = eValueTypeVariableGlobal;
3468 else
3469 scope = eValueTypeVariableLocal;
3470
3471 SymbolContextScope * symbol_context_scope = NULL;
3472 if (parent_tag == DW_TAG_compile_unit)
3473 {
3474 symbol_context_scope = sc.comp_unit;
3475 }
3476 else if (sc.function != NULL)
3477 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003478 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003479 if (symbol_context_scope == NULL)
3480 symbol_context_scope = sc.function;
3481 }
3482
3483 assert(symbol_context_scope != NULL);
3484 var_sp.reset (new Variable(die->GetOffset(),
3485 var_name,
3486 var_type,
3487 scope,
3488 symbol_context_scope,
3489 &decl,
3490 location,
3491 is_external,
3492 is_artificial));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003493
3494 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003495 }
3496 }
3497 return var_sp;
3498}
3499
3500size_t
3501SymbolFileDWARF::ParseVariables
3502(
3503 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003504 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00003505 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003506 const DWARFDebugInfoEntry *orig_die,
3507 bool parse_siblings,
3508 bool parse_children,
3509 VariableList* cc_variable_list
3510)
3511{
3512 if (orig_die == NULL)
3513 return 0;
3514
3515 size_t vars_added = 0;
3516 const DWARFDebugInfoEntry *die = orig_die;
3517 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
3518 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3519 VariableListSP variables;
3520 switch (parent_tag)
3521 {
3522 case DW_TAG_compile_unit:
3523 if (sc.comp_unit != NULL)
3524 {
3525 variables = sc.comp_unit->GetVariableList(false);
3526 if (variables.get() == NULL)
3527 {
3528 variables.reset(new VariableList());
3529 sc.comp_unit->SetVariableList(variables);
3530 }
3531 }
3532 else
3533 {
3534 assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
3535 vars_added = 0;
3536 }
3537 break;
3538
3539 case DW_TAG_subprogram:
3540 case DW_TAG_inlined_subroutine:
3541 case DW_TAG_lexical_block:
3542 if (sc.function != NULL)
3543 {
3544 // Check to see if we already have parsed the variables for the given scope
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003545
3546 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
3547 assert (block != NULL);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003548 variables = block->GetVariableList(false, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003549 if (variables.get() == NULL)
3550 {
3551 variables.reset(new VariableList());
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003552 block->SetVariableList(variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003553 }
3554 }
3555 else
3556 {
3557 assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
3558 vars_added = 0;
3559 }
3560 break;
3561
3562 default:
3563 assert(!"Didn't find appropriate parent DIE for variable list...");
3564 break;
3565 }
3566
3567 // We need to have a variable list at this point that we can add variables to
3568 assert(variables.get());
3569
3570 while (die != NULL)
3571 {
3572 dw_tag_t tag = die->Tag();
3573
3574 // Check to see if we have already parsed this variable or constant?
Greg Clayton594e5ed2010-09-27 21:07:38 +00003575 if (m_die_to_variable_sp[die].get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003576 {
3577 // We haven't already parsed it, lets do that now.
3578 if ((tag == DW_TAG_variable) ||
3579 (tag == DW_TAG_constant) ||
3580 (tag == DW_TAG_formal_parameter && sc.function))
3581 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003582 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003583 if (var_sp)
3584 {
3585 variables->AddVariable(var_sp);
3586 ++vars_added;
3587 }
3588 }
3589 }
3590
3591 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
3592
3593 if (!skip_children && parse_children && die->HasChildren())
3594 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003595 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003596 //vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), parse_siblings, parse_children);
3597 }
3598
3599 if (parse_siblings)
3600 die = die->GetSibling();
3601 else
3602 die = NULL;
3603 }
3604
3605 if (cc_variable_list)
3606 {
3607 cc_variable_list->AddVariables(variables.get());
3608 }
3609
3610 return vars_added;
3611}
3612
3613//------------------------------------------------------------------
3614// PluginInterface protocol
3615//------------------------------------------------------------------
3616const char *
3617SymbolFileDWARF::GetPluginName()
3618{
3619 return "SymbolFileDWARF";
3620}
3621
3622const char *
3623SymbolFileDWARF::GetShortPluginName()
3624{
3625 return GetPluginNameStatic();
3626}
3627
3628uint32_t
3629SymbolFileDWARF::GetPluginVersion()
3630{
3631 return 1;
3632}
3633
3634void
3635SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
3636{
3637}
3638
3639Error
3640SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
3641{
3642 Error error;
3643 error.SetErrorString("No plug-in command are currently supported.");
3644 return error;
3645}
3646
3647Log *
3648SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
3649{
3650 return NULL;
3651}
3652