blob: 40ef595395445b57569cc7cee5c62648a625e9fc [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"
Greg Clayton450e3f32010-10-12 02:24:53 +000052#include "SymbolFileDWARFDebugMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053
54#include <map>
55
Greg Claytonc93237c2010-10-01 20:48:32 +000056//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
57
58#ifdef ENABLE_DEBUG_PRINTF
59#include <stdio.h>
60#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
61#else
62#define DEBUG_PRINTF(fmt, ...)
63#endif
64
Greg Clayton594e5ed2010-09-27 21:07:38 +000065#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066
67using namespace lldb;
68using namespace lldb_private;
69
70
Sean Callananc7fbf732010-08-06 00:32:49 +000071static AccessType
Greg Clayton8cf05932010-07-22 18:30:50 +000072DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073{
74 switch (dwarf_accessibility)
75 {
Sean Callananc7fbf732010-08-06 00:32:49 +000076 case DW_ACCESS_public: return eAccessPublic;
77 case DW_ACCESS_private: return eAccessPrivate;
78 case DW_ACCESS_protected: return eAccessProtected;
Greg Clayton8cf05932010-07-22 18:30:50 +000079 default: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080 }
Sean Callananc7fbf732010-08-06 00:32:49 +000081 return eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000082}
83
84void
85SymbolFileDWARF::Initialize()
86{
87 LogChannelDWARF::Initialize();
88 PluginManager::RegisterPlugin (GetPluginNameStatic(),
89 GetPluginDescriptionStatic(),
90 CreateInstance);
91}
92
93void
94SymbolFileDWARF::Terminate()
95{
96 PluginManager::UnregisterPlugin (CreateInstance);
97 LogChannelDWARF::Initialize();
98}
99
100
101const char *
102SymbolFileDWARF::GetPluginNameStatic()
103{
104 return "symbol-file.dwarf2";
105}
106
107const char *
108SymbolFileDWARF::GetPluginDescriptionStatic()
109{
110 return "DWARF and DWARF3 debug symbol file reader.";
111}
112
113
114SymbolFile*
115SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
116{
117 return new SymbolFileDWARF(obj_file);
118}
119
120//----------------------------------------------------------------------
121// Gets the first parent that is a lexical block, function or inlined
122// subroutine, or compile unit.
123//----------------------------------------------------------------------
124static const DWARFDebugInfoEntry *
125GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
126{
127 const DWARFDebugInfoEntry *die;
128 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
129 {
130 dw_tag_t tag = die->Tag();
131
132 switch (tag)
133 {
134 case DW_TAG_compile_unit:
135 case DW_TAG_subprogram:
136 case DW_TAG_inlined_subroutine:
137 case DW_TAG_lexical_block:
138 return die;
139 }
140 }
141 return NULL;
142}
143
144
Greg Clayton450e3f32010-10-12 02:24:53 +0000145SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
146 SymbolFile (objfile),
147 m_debug_map_symfile (NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148 m_flags(),
149 m_data_debug_abbrev(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000150 m_data_debug_frame(),
151 m_data_debug_info(),
152 m_data_debug_line(),
153 m_data_debug_loc(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000154 m_data_debug_ranges(),
155 m_data_debug_str(),
156 m_abbr(),
157 m_aranges(),
158 m_info(),
159 m_line(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000160 m_function_basename_index(),
161 m_function_fullname_index(),
162 m_function_method_index(),
163 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000164 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000165 m_global_index(),
166 m_types_index(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167 m_indexed(false),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000168 m_ranges()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169{
170}
171
172SymbolFileDWARF::~SymbolFileDWARF()
173{
174}
175
176bool
177SymbolFileDWARF::SupportedVersion(uint16_t version)
178{
179 return version == 2 || version == 3;
180}
181
182uint32_t
183SymbolFileDWARF::GetAbilities ()
184{
185 uint32_t abilities = 0;
186 if (m_obj_file != NULL)
187 {
188 const Section* section = NULL;
189 const SectionList *section_list = m_obj_file->GetSectionList();
190 if (section_list == NULL)
191 return 0;
192
193 uint64_t debug_abbrev_file_size = 0;
194 uint64_t debug_aranges_file_size = 0;
195 uint64_t debug_frame_file_size = 0;
196 uint64_t debug_info_file_size = 0;
197 uint64_t debug_line_file_size = 0;
198 uint64_t debug_loc_file_size = 0;
199 uint64_t debug_macinfo_file_size = 0;
200 uint64_t debug_pubnames_file_size = 0;
201 uint64_t debug_pubtypes_file_size = 0;
202 uint64_t debug_ranges_file_size = 0;
203 uint64_t debug_str_file_size = 0;
204
205 static ConstString g_dwarf_section_name ("__DWARF");
206
207 section = section_list->FindSectionByName(g_dwarf_section_name).get();
208
209 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000210 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000211 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
Greg Clayton4ceb9982010-07-21 22:54:26 +0000212 section_list = &section->GetChildren ();
213 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000214
Greg Clayton4ceb9982010-07-21 22:54:26 +0000215 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000216 if (section != NULL)
217 {
218 debug_info_file_size = section->GetByteSize();
219
Greg Clayton4ceb9982010-07-21 22:54:26 +0000220 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000221 if (section)
222 debug_abbrev_file_size = section->GetByteSize();
223 else
224 m_flags.Set (flagsGotDebugAbbrevData);
225
Greg Clayton4ceb9982010-07-21 22:54:26 +0000226 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000227 if (section)
228 debug_aranges_file_size = section->GetByteSize();
229 else
230 m_flags.Set (flagsGotDebugArangesData);
231
Greg Clayton4ceb9982010-07-21 22:54:26 +0000232 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000233 if (section)
234 debug_frame_file_size = section->GetByteSize();
235 else
236 m_flags.Set (flagsGotDebugFrameData);
237
Greg Clayton4ceb9982010-07-21 22:54:26 +0000238 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000239 if (section)
240 debug_line_file_size = section->GetByteSize();
241 else
242 m_flags.Set (flagsGotDebugLineData);
243
Greg Clayton4ceb9982010-07-21 22:54:26 +0000244 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245 if (section)
246 debug_loc_file_size = section->GetByteSize();
247 else
248 m_flags.Set (flagsGotDebugLocData);
249
Greg Clayton4ceb9982010-07-21 22:54:26 +0000250 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000251 if (section)
252 debug_macinfo_file_size = section->GetByteSize();
253 else
254 m_flags.Set (flagsGotDebugMacInfoData);
255
Greg Clayton4ceb9982010-07-21 22:54:26 +0000256 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000257 if (section)
258 debug_pubnames_file_size = section->GetByteSize();
259 else
260 m_flags.Set (flagsGotDebugPubNamesData);
261
Greg Clayton4ceb9982010-07-21 22:54:26 +0000262 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263 if (section)
264 debug_pubtypes_file_size = section->GetByteSize();
265 else
266 m_flags.Set (flagsGotDebugPubTypesData);
267
Greg Clayton4ceb9982010-07-21 22:54:26 +0000268 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269 if (section)
270 debug_ranges_file_size = section->GetByteSize();
271 else
272 m_flags.Set (flagsGotDebugRangesData);
273
Greg Clayton4ceb9982010-07-21 22:54:26 +0000274 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000275 if (section)
276 debug_str_file_size = section->GetByteSize();
277 else
278 m_flags.Set (flagsGotDebugStrData);
279 }
280
281 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
282 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
283
284 if (debug_line_file_size > 0)
285 abilities |= LineTables;
286
287 if (debug_aranges_file_size > 0)
288 abilities |= AddressAcceleratorTable;
289
290 if (debug_pubnames_file_size > 0)
291 abilities |= FunctionAcceleratorTable;
292
293 if (debug_pubtypes_file_size > 0)
294 abilities |= TypeAcceleratorTable;
295
296 if (debug_macinfo_file_size > 0)
297 abilities |= MacroInformation;
298
299 if (debug_frame_file_size > 0)
300 abilities |= CallFrameInformation;
301 }
302 return abilities;
303}
304
305const DataExtractor&
Greg Clayton4ceb9982010-07-21 22:54:26 +0000306SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000307{
308 if (m_flags.IsClear (got_flag))
309 {
310 m_flags.Set (got_flag);
311 const SectionList *section_list = m_obj_file->GetSectionList();
312 if (section_list)
313 {
Greg Clayton4ceb9982010-07-21 22:54:26 +0000314 Section *section = section_list->FindSectionByType(sect_type, true).get();
315 if (section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000316 {
317 // See if we memory mapped the DWARF segment?
318 if (m_dwarf_data.GetByteSize())
319 {
320 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
321 }
322 else
323 {
324 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
325 data.Clear();
326 }
327 }
328 }
329 }
330 return data;
331}
332
333const DataExtractor&
334SymbolFileDWARF::get_debug_abbrev_data()
335{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000336 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337}
338
339const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340SymbolFileDWARF::get_debug_frame_data()
341{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000342 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343}
344
345const DataExtractor&
346SymbolFileDWARF::get_debug_info_data()
347{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000348 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349}
350
351const DataExtractor&
352SymbolFileDWARF::get_debug_line_data()
353{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000354 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000355}
356
357const DataExtractor&
358SymbolFileDWARF::get_debug_loc_data()
359{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000360 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361}
362
363const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000364SymbolFileDWARF::get_debug_ranges_data()
365{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000366 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000367}
368
369const DataExtractor&
370SymbolFileDWARF::get_debug_str_data()
371{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000372 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373}
374
375
376DWARFDebugAbbrev*
377SymbolFileDWARF::DebugAbbrev()
378{
379 if (m_abbr.get() == NULL)
380 {
381 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
382 if (debug_abbrev_data.GetByteSize() > 0)
383 {
384 m_abbr.reset(new DWARFDebugAbbrev());
385 if (m_abbr.get())
386 m_abbr->Parse(debug_abbrev_data);
387 }
388 }
389 return m_abbr.get();
390}
391
392const DWARFDebugAbbrev*
393SymbolFileDWARF::DebugAbbrev() const
394{
395 return m_abbr.get();
396}
397
398DWARFDebugAranges*
399SymbolFileDWARF::DebugAranges()
400{
Greg Clayton016a95e2010-09-14 02:20:48 +0000401 // It turns out that llvm-gcc doesn't generate .debug_aranges in .o files
402 // and we are already parsing all of the DWARF because the .debug_pubnames
403 // is useless (it only mentions symbols that are externally visible), so
404 // don't use the .debug_aranges section, we should be using a debug aranges
405 // we got from SymbolFileDWARF::Index().
406
407 if (!m_indexed)
408 Index();
409
410
411// if (m_aranges.get() == NULL)
412// {
413// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
414// m_aranges.reset(new DWARFDebugAranges());
415// if (m_aranges.get())
416// {
417// const DataExtractor &debug_aranges_data = get_debug_aranges_data();
418// if (debug_aranges_data.GetByteSize() > 0)
419// m_aranges->Extract(debug_aranges_data);
420// else
421// m_aranges->Generate(this);
422// }
423// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000424 return m_aranges.get();
425}
426
427const DWARFDebugAranges*
428SymbolFileDWARF::DebugAranges() const
429{
430 return m_aranges.get();
431}
432
433
434DWARFDebugInfo*
435SymbolFileDWARF::DebugInfo()
436{
437 if (m_info.get() == NULL)
438 {
439 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
440 if (get_debug_info_data().GetByteSize() > 0)
441 {
442 m_info.reset(new DWARFDebugInfo());
443 if (m_info.get())
444 {
445 m_info->SetDwarfData(this);
446 }
447 }
448 }
449 return m_info.get();
450}
451
452const DWARFDebugInfo*
453SymbolFileDWARF::DebugInfo() const
454{
455 return m_info.get();
456}
457
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000458DWARFCompileUnit*
459SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
460{
461 DWARFDebugInfo* info = DebugInfo();
462 if (info)
463 return info->GetCompileUnit(cu_uid).get();
464 return NULL;
465}
466
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467
468DWARFDebugRanges*
469SymbolFileDWARF::DebugRanges()
470{
471 if (m_ranges.get() == NULL)
472 {
473 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
474 if (get_debug_ranges_data().GetByteSize() > 0)
475 {
476 m_ranges.reset(new DWARFDebugRanges());
477 if (m_ranges.get())
478 m_ranges->Extract(this);
479 }
480 }
481 return m_ranges.get();
482}
483
484const DWARFDebugRanges*
485SymbolFileDWARF::DebugRanges() const
486{
487 return m_ranges.get();
488}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489
490bool
Greg Clayton0fffff52010-09-24 05:15:53 +0000491SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000492{
493 if (cu != NULL)
494 {
495 const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly ();
496 if (cu_die)
497 {
498 const char * cu_die_name = cu_die->GetName(this, cu);
499 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL);
Greg Clayton9e409562010-07-28 02:04:09 +0000500 LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_language, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000501 if (cu_die_name)
502 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000503 FileSpec cu_file_spec;
504
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000505 if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0])
506 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000507 // If we have a full path to the compile unit, we don't need to resolve
508 // the file. This can be expensive e.g. when the source files are NFS mounted.
509 cu_file_spec.SetFile (cu_die_name, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000510 }
511 else
512 {
513 std::string fullpath(cu_comp_dir);
514 if (*fullpath.rbegin() != '/')
515 fullpath += '/';
516 fullpath += cu_die_name;
Jim Ingham0909e5f2010-09-16 00:57:33 +0000517 cu_file_spec.SetFile (fullpath.c_str(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000518 }
519
Jim Ingham0909e5f2010-09-16 00:57:33 +0000520 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 +0000521 if (compile_unit_sp.get())
522 {
523 cu->SetUserData(compile_unit_sp.get());
524 return true;
525 }
526 }
527 }
528 }
529 return false;
530}
531
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000532uint32_t
533SymbolFileDWARF::GetNumCompileUnits()
534{
535 DWARFDebugInfo* info = DebugInfo();
536 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000537 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000538 return 0;
539}
540
541CompUnitSP
542SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
543{
544 CompUnitSP comp_unit;
545 DWARFDebugInfo* info = DebugInfo();
546 if (info)
547 {
548 DWARFCompileUnit* cu = info->GetCompileUnitAtIndex(cu_idx);
549 if (cu != NULL)
550 {
551 // Our symbol vendor shouldn't be asking us to add a compile unit that
552 // has already been added to it, which this DWARF plug-in knows as it
553 // stores the lldb compile unit (CompileUnit) pointer in each
554 // DWARFCompileUnit object when it gets added.
555 assert(cu->GetUserData() == NULL);
556 ParseCompileUnit(cu, comp_unit);
557 }
558 }
559 return comp_unit;
560}
561
562static void
563AddRangesToBlock
564(
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000565 Block& block,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000566 DWARFDebugRanges::RangeList& ranges,
567 addr_t block_base_addr
568)
569{
570 ranges.SubtractOffset (block_base_addr);
571 size_t range_idx = 0;
572 const DWARFDebugRanges::Range *debug_range;
573 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
574 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000575 block.AddRange(debug_range->begin_offset, debug_range->end_offset);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000576 }
577}
578
579
580Function *
Greg Clayton0fffff52010-09-24 05:15:53 +0000581SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000582{
583 DWARFDebugRanges::RangeList func_ranges;
584 const char *name = NULL;
585 const char *mangled = NULL;
586 int decl_file = 0;
587 int decl_line = 0;
588 int decl_column = 0;
589 int call_file = 0;
590 int call_line = 0;
591 int call_column = 0;
592 DWARFExpression frame_base;
593
Greg Claytonc93237c2010-10-01 20:48:32 +0000594 assert (die->Tag() == DW_TAG_subprogram);
595
596 if (die->Tag() != DW_TAG_subprogram)
597 return NULL;
598
599 const DWARFDebugInfoEntry *parent_die = die->GetParent();
600 switch (parent_die->Tag())
601 {
602 case DW_TAG_structure_type:
603 case DW_TAG_class_type:
604 // We have methods of a class or struct
605 {
606 Type *class_type = ResolveType (dwarf_cu, parent_die);
607 if (class_type)
608 class_type->GetClangType();
609 }
610 break;
611
612 default:
613 // Parse the function prototype as a type that can then be added to concrete function instance
614 ParseTypes (sc, dwarf_cu, die, false, false);
615 break;
616 }
617
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000618 //FixupTypes();
619
620 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
621 {
622 // Union of all ranges in the function DIE (if the function is discontiguous)
623 AddressRange func_range;
624 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
625 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
626 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
627 {
628 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
629 if (func_range.GetBaseAddress().IsValid())
630 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
631 }
632
633 if (func_range.GetBaseAddress().IsValid())
634 {
635 Mangled func_name;
636 if (mangled)
637 func_name.SetValue(mangled, true);
638 else if (name)
639 func_name.SetValue(name, false);
640
641 FunctionSP func_sp;
642 std::auto_ptr<Declaration> decl_ap;
643 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
644 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column));
645
Greg Clayton594e5ed2010-09-27 21:07:38 +0000646 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000647
648 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
649
650 func_range.GetBaseAddress().ResolveLinkedAddress();
651
652 func_sp.reset(new Function (sc.comp_unit,
653 die->GetOffset(), // UserID is the DIE offset
654 die->GetOffset(),
655 func_name,
656 func_type,
657 func_range)); // first address range
658
659 if (func_sp.get() != NULL)
660 {
661 func_sp->GetFrameBaseExpression() = frame_base;
662 sc.comp_unit->AddFunction(func_sp);
663 return func_sp.get();
664 }
665 }
666 }
667 return NULL;
668}
669
670size_t
671SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
672{
673 assert (sc.comp_unit);
674 size_t functions_added = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +0000675 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000676 if (dwarf_cu)
677 {
678 DWARFDIECollection function_dies;
679 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
680 size_t func_idx;
681 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
682 {
683 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
684 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
685 {
686 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
687 ++functions_added;
688 }
689 }
690 //FixupTypes();
691 }
692 return functions_added;
693}
694
695bool
696SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
697{
698 assert (sc.comp_unit);
699 DWARFCompileUnit* cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
700 assert (cu);
701 const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly();
702
703 if (cu_die)
704 {
705 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL);
706 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
707
708 // All file indexes in DWARF are one based and a file of index zero is
709 // supposed to be the compile unit itself.
710 support_files.Append (*sc.comp_unit);
711
712 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
713 }
714 return false;
715}
716
717struct ParseDWARFLineTableCallbackInfo
718{
719 LineTable* line_table;
720 const SectionList *section_list;
721 lldb::addr_t prev_sect_file_base_addr;
722 lldb::addr_t curr_sect_file_base_addr;
723 bool is_oso_for_debug_map;
724 bool prev_in_final_executable;
725 DWARFDebugLine::Row prev_row;
726 SectionSP prev_section_sp;
727 SectionSP curr_section_sp;
728};
729
730//----------------------------------------------------------------------
731// ParseStatementTableCallback
732//----------------------------------------------------------------------
733static void
734ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
735{
736 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
737 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
738 {
739 // Just started parsing the line table
740 }
741 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
742 {
743 // Done parsing line table, nothing to do for the cleanup
744 }
745 else
746 {
747 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
748 // We have a new row, lets append it
749
750 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
751 {
752 info->prev_section_sp = info->curr_section_sp;
753 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
754 // If this is an end sequence entry, then we subtract one from the
755 // address to make sure we get an address that is not the end of
756 // a section.
757 if (state.end_sequence && state.address != 0)
758 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
759 else
760 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
761
762 if (info->curr_section_sp.get())
763 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
764 else
765 info->curr_sect_file_base_addr = 0;
766 }
767 if (info->curr_section_sp.get())
768 {
769 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
770 // Check for the fancy section magic to determine if we
771
772 if (info->is_oso_for_debug_map)
773 {
774 // When this is a debug map object file that contains DWARF
775 // (referenced from an N_OSO debug map nlist entry) we will have
776 // a file address in the file range for our section from the
777 // original .o file, and a load address in the executable that
778 // contains the debug map.
779 //
780 // If the sections for the file range and load range are
781 // different, we have a remapped section for the function and
782 // this address is resolved. If they are the same, then the
783 // function for this address didn't make it into the final
784 // executable.
785 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
786
787 // If we are doing DWARF with debug map, then we need to carefully
788 // add each line table entry as there may be gaps as functions
789 // get moved around or removed.
790 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
791 {
792 if (info->prev_in_final_executable)
793 {
794 bool terminate_previous_entry = false;
795 if (!curr_in_final_executable)
796 {
797 // Check for the case where the previous line entry
798 // in a function made it into the final executable,
799 // yet the current line entry falls in a function
800 // that didn't. The line table used to be contiguous
801 // through this address range but now it isn't. We
802 // need to terminate the previous line entry so
803 // that we can reconstruct the line range correctly
804 // for it and to keep the line table correct.
805 terminate_previous_entry = true;
806 }
807 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
808 {
809 // Check for cases where the line entries used to be
810 // contiguous address ranges, but now they aren't.
811 // This can happen when order files specify the
812 // ordering of the functions.
813 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
814 Section *curr_sect = info->curr_section_sp.get();
815 Section *prev_sect = info->prev_section_sp.get();
816 assert (curr_sect->GetLinkedSection());
817 assert (prev_sect->GetLinkedSection());
818 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
819 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
820 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
821 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
822 if (object_file_addr_delta != linked_file_addr_delta)
823 terminate_previous_entry = true;
824 }
825
826 if (terminate_previous_entry)
827 {
828 line_table->InsertLineEntry (info->prev_section_sp,
829 state.address - info->prev_sect_file_base_addr,
830 info->prev_row.line,
831 info->prev_row.column,
832 info->prev_row.file,
833 false, // is_stmt
834 false, // basic_block
835 false, // state.prologue_end
836 false, // state.epilogue_begin
837 true); // end_sequence);
838 }
839 }
840 }
841
842 if (curr_in_final_executable)
843 {
844 line_table->InsertLineEntry (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 info->prev_section_sp = info->curr_section_sp;
855 }
856 else
857 {
858 // If the current address didn't make it into the final
859 // executable, the current section will be the __text
860 // segment in the .o file, so we need to clear this so
861 // we can catch the next function that did make it into
862 // the final executable.
863 info->prev_section_sp.reset();
864 info->curr_section_sp.reset();
865 }
866
867 info->prev_in_final_executable = curr_in_final_executable;
868 }
869 else
870 {
871 // We are not in an object file that contains DWARF for an
872 // N_OSO, this is just a normal DWARF file. The DWARF spec
873 // guarantees that the addresses will be in increasing order
874 // so, since we store line tables in file address order, we
875 // can always just append the line entry without needing to
876 // search for the correct insertion point (we don't need to
877 // use LineEntry::InsertLineEntry()).
878 line_table->AppendLineEntry (info->curr_section_sp,
879 curr_line_section_offset,
880 state.line,
881 state.column,
882 state.file,
883 state.is_stmt,
884 state.basic_block,
885 state.prologue_end,
886 state.epilogue_begin,
887 state.end_sequence);
888 }
889 }
890
891 info->prev_row = state;
892 }
893}
894
895bool
896SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
897{
898 assert (sc.comp_unit);
899 if (sc.comp_unit->GetLineTable() != NULL)
900 return true;
901
902 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
903 if (dwarf_cu)
904 {
905 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
906 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
907 if (cu_line_offset != DW_INVALID_OFFSET)
908 {
909 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
910 if (line_table_ap.get())
911 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000912 ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_debug_map_symfile != NULL, false};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000913 uint32_t offset = cu_line_offset;
914 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
915 sc.comp_unit->SetLineTable(line_table_ap.release());
916 return true;
917 }
918 }
919 }
920 return false;
921}
922
923size_t
924SymbolFileDWARF::ParseFunctionBlocks
925(
926 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000927 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +0000928 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000929 const DWARFDebugInfoEntry *die,
930 addr_t subprogram_low_pc,
931 bool parse_siblings,
932 bool parse_children
933)
934{
935 size_t blocks_added = 0;
936 while (die != NULL)
937 {
938 dw_tag_t tag = die->Tag();
939
940 switch (tag)
941 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000942 case DW_TAG_inlined_subroutine:
Jim Inghamb0be4422010-08-12 01:20:14 +0000943 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000944 case DW_TAG_lexical_block:
945 {
946 DWARFDebugRanges::RangeList ranges;
947 const char *name = NULL;
948 const char *mangled_name = NULL;
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000949 Block *block = NULL;
950 if (tag != DW_TAG_subprogram)
951 {
952 BlockSP block_sp(new Block (die->GetOffset()));
953 parent_block->AddChild(block_sp);
954 block = block_sp.get();
955 }
956 else
957 {
958 block = parent_block;
959 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000960
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000961 int decl_file = 0;
962 int decl_line = 0;
963 int decl_column = 0;
964 int call_file = 0;
965 int call_line = 0;
966 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000967 if (die->GetDIENamesAndRanges (this,
968 dwarf_cu,
969 name,
970 mangled_name,
971 ranges,
972 decl_file, decl_line, decl_column,
973 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000974 {
975 if (tag == DW_TAG_subprogram)
976 {
977 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
978 subprogram_low_pc = ranges.LowestAddress(0);
979 }
Jim Inghamb0be4422010-08-12 01:20:14 +0000980 else if (tag == DW_TAG_inlined_subroutine)
981 {
982 // We get called here for inlined subroutines in two ways.
983 // The first time is when we are making the Function object
984 // for this inlined concrete instance. Since we're creating a top level block at
985 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
986 // adjust the containing address.
987 // The second time is when we are parsing the blocks inside the function that contains
988 // the inlined concrete instance. Since these will be blocks inside the containing "real"
989 // function the offset will be for that function.
990 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
991 {
992 subprogram_low_pc = ranges.LowestAddress(0);
993 }
994 }
995
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000996 AddRangesToBlock (*block, ranges, subprogram_low_pc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000997
998 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
999 {
1000 std::auto_ptr<Declaration> decl_ap;
1001 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001002 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1003 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001004
1005 std::auto_ptr<Declaration> call_ap;
1006 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001007 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1008 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001009
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001010 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001011 }
1012
1013 ++blocks_added;
1014
1015 if (parse_children && die->HasChildren())
1016 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001017 blocks_added += ParseFunctionBlocks (sc,
1018 block,
1019 dwarf_cu,
1020 die->GetFirstChild(),
1021 subprogram_low_pc,
1022 true,
1023 true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001024 }
1025 }
1026 }
1027 break;
1028 default:
1029 break;
1030 }
1031
1032 if (parse_siblings)
1033 die = die->GetSibling();
1034 else
1035 die = NULL;
1036 }
1037 return blocks_added;
1038}
1039
1040size_t
1041SymbolFileDWARF::ParseChildMembers
1042(
1043 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001044 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001045 const DWARFDebugInfoEntry *parent_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001046 clang_type_t class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001047 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001048 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1049 std::vector<int>& member_accessibilities,
Greg Claytonc93237c2010-10-01 20:48:32 +00001050 DWARFDIECollection& member_function_dies,
Sean Callananc7fbf732010-08-06 00:32:49 +00001051 AccessType& default_accessibility,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001052 bool &is_a_class
1053)
1054{
1055 if (parent_die == NULL)
1056 return 0;
1057
1058 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
1059
1060 size_t count = 0;
1061 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00001062 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
1063
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001064 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1065 {
1066 dw_tag_t tag = die->Tag();
1067
1068 switch (tag)
1069 {
1070 case DW_TAG_member:
1071 {
1072 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00001073 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001074 if (num_attributes > 0)
1075 {
1076 Declaration decl;
1077 DWARFExpression location;
1078 const char *name = NULL;
1079 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001080 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001081 off_t member_offset = 0;
1082 size_t byte_size = 0;
1083 size_t bit_offset = 0;
1084 size_t bit_size = 0;
1085 uint32_t i;
1086 for (i=0; i<num_attributes; ++i)
1087 {
1088 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1089 DWARFFormValue form_value;
1090 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1091 {
1092 switch (attr)
1093 {
1094 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1095 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1096 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1097 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1098 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1099 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1100 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1101 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1102 case DW_AT_data_member_location:
1103 if (form_value.BlockData())
1104 {
1105 Value initialValue(0);
1106 Value memberOffset(0);
1107 const DataExtractor& debug_info_data = get_debug_info_data();
1108 uint32_t block_length = form_value.Unsigned();
1109 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1110 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1111 {
1112 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1113 }
1114 }
1115 break;
1116
Greg Clayton8cf05932010-07-22 18:30:50 +00001117 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001118 case DW_AT_declaration:
1119 case DW_AT_description:
1120 case DW_AT_mutable:
1121 case DW_AT_visibility:
1122 default:
1123 case DW_AT_sibling:
1124 break;
1125 }
1126 }
1127 }
1128
1129 Type *member_type = ResolveTypeUID(encoding_uid);
1130 assert(member_type);
Sean Callananc7fbf732010-08-06 00:32:49 +00001131 if (accessibility == eAccessNone)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001132 accessibility = default_accessibility;
1133 member_accessibilities.push_back(accessibility);
1134
Greg Clayton1be10fc2010-09-29 01:12:09 +00001135 type_list->GetClangASTContext().AddFieldToRecordType (class_clang_type, name, member_type->GetClangType(), accessibility, bit_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001136 }
1137 }
1138 break;
1139
1140 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00001141 // Let the type parsing code handle this one for us.
1142 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001143 break;
1144
1145 case DW_TAG_inheritance:
1146 {
1147 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00001148 if (default_accessibility == eAccessNone)
1149 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001150 // TODO: implement DW_TAG_inheritance type parsing
1151 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00001152 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001153 if (num_attributes > 0)
1154 {
1155 Declaration decl;
1156 DWARFExpression location;
1157 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001158 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001159 bool is_virtual = false;
1160 bool is_base_of_class = true;
1161 off_t member_offset = 0;
1162 uint32_t i;
1163 for (i=0; i<num_attributes; ++i)
1164 {
1165 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1166 DWARFFormValue form_value;
1167 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1168 {
1169 switch (attr)
1170 {
1171 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1172 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1173 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1174 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1175 case DW_AT_data_member_location:
1176 if (form_value.BlockData())
1177 {
1178 Value initialValue(0);
1179 Value memberOffset(0);
1180 const DataExtractor& debug_info_data = get_debug_info_data();
1181 uint32_t block_length = form_value.Unsigned();
1182 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1183 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1184 {
1185 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1186 }
1187 }
1188 break;
1189
1190 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00001191 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001192 break;
1193
1194 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1195 default:
1196 case DW_AT_sibling:
1197 break;
1198 }
1199 }
1200 }
1201
1202 Type *base_class_dctype = ResolveTypeUID(encoding_uid);
1203 assert(base_class_dctype);
Greg Clayton9e409562010-07-28 02:04:09 +00001204
1205 if (class_language == eLanguageTypeObjC)
1206 {
Greg Clayton1be10fc2010-09-29 01:12:09 +00001207 type_list->GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_dctype->GetClangType());
Greg Clayton9e409562010-07-28 02:04:09 +00001208 }
1209 else
1210 {
Greg Clayton1be10fc2010-09-29 01:12:09 +00001211 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 +00001212 assert(base_classes.back());
1213 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001214 }
1215 }
1216 break;
1217
1218 default:
1219 break;
1220 }
1221 }
1222 return count;
1223}
1224
1225
1226clang::DeclContext*
1227SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1228{
1229 DWARFDebugInfo* debug_info = DebugInfo();
1230 if (debug_info)
1231 {
1232 DWARFCompileUnitSP cu_sp;
1233 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1234 if (die)
1235 return GetClangDeclContextForDIE (cu_sp.get(), die);
1236 }
1237 return NULL;
1238}
1239
1240Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001241SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001242{
1243 DWARFDebugInfo* debug_info = DebugInfo();
1244 if (debug_info)
1245 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001246 DWARFCompileUnitSP cu_sp;
1247 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001248 if (type_die != NULL)
Greg Clayton594e5ed2010-09-27 21:07:38 +00001249 return ResolveType (cu_sp.get(), type_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001250 }
1251 return NULL;
1252}
1253
Greg Clayton1be10fc2010-09-29 01:12:09 +00001254lldb::clang_type_t
1255SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1256{
1257 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Claytonc93237c2010-10-01 20:48:32 +00001258 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (ClangASTType::RemoveFastQualifiers(clang_type));
Greg Clayton1be10fc2010-09-29 01:12:09 +00001259 assert (die);
1260 if (die == NULL)
1261 return NULL;
1262
Greg Clayton450e3f32010-10-12 02:24:53 +00001263 DWARFDebugInfo* debug_info = DebugInfo();
1264
1265 DWARFCompileUnit *cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001266 Type *type = m_die_to_type.lookup (die);
1267
1268 const dw_tag_t tag = die->Tag();
1269
Greg Claytonc93237c2010-10-01 20:48:32 +00001270 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n", die->GetOffset(), DW_TAG_value_to_name(tag), type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001271 assert (clang_type);
1272 DWARFDebugInfoEntry::Attributes attributes;
1273
1274 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
1275
1276 switch (tag)
1277 {
1278 case DW_TAG_structure_type:
1279 case DW_TAG_union_type:
1280 case DW_TAG_class_type:
Greg Claytonc93237c2010-10-01 20:48:32 +00001281 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
1282 if (die->HasChildren())
1283 {
1284 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton450e3f32010-10-12 02:24:53 +00001285 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1286 if (is_objc_class)
Greg Claytonc93237c2010-10-01 20:48:32 +00001287 class_language = eLanguageTypeObjC;
1288
1289 int tag_decl_kind = -1;
1290 AccessType default_accessibility = eAccessNone;
1291 if (tag == DW_TAG_structure_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001292 {
Greg Claytonc93237c2010-10-01 20:48:32 +00001293 tag_decl_kind = clang::TTK_Struct;
1294 default_accessibility = eAccessPublic;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001295 }
Greg Claytonc93237c2010-10-01 20:48:32 +00001296 else if (tag == DW_TAG_union_type)
1297 {
1298 tag_decl_kind = clang::TTK_Union;
1299 default_accessibility = eAccessPublic;
1300 }
1301 else if (tag == DW_TAG_class_type)
1302 {
1303 tag_decl_kind = clang::TTK_Class;
1304 default_accessibility = eAccessPrivate;
1305 }
1306
1307 SymbolContext sc(GetCompUnitForDWARFCompUnit(cu));
1308 std::vector<clang::CXXBaseSpecifier *> base_classes;
1309 std::vector<int> member_accessibilities;
1310 bool is_a_class = false;
1311 // Parse members and base classes first
1312 DWARFDIECollection member_function_dies;
1313
1314 ParseChildMembers (sc,
1315 cu,
1316 die,
1317 clang_type,
1318 class_language,
1319 base_classes,
1320 member_accessibilities,
1321 member_function_dies,
1322 default_accessibility,
1323 is_a_class);
1324
1325 // Now parse any methods if there were any...
1326 size_t num_functions = member_function_dies.Size();
1327 if (num_functions > 0)
1328 {
1329 for (size_t i=0; i<num_functions; ++i)
1330 {
1331 ResolveType(cu, member_function_dies.GetDIEPtrAtIndex(i));
1332 }
1333 }
1334
Greg Clayton450e3f32010-10-12 02:24:53 +00001335 if (class_language == eLanguageTypeObjC)
1336 {
1337 std::string class_str (ClangASTContext::GetTypeName (clang_type));
1338 if (!class_str.empty())
1339 {
1340
1341 ConstString class_name (class_str.c_str());
1342 std::vector<NameToDIE::Info> method_die_infos;
1343 if (m_objc_class_selectors_index.Find (class_name, method_die_infos))
1344 {
1345 DWARFCompileUnit* method_cu = NULL;
1346 DWARFCompileUnit* prev_method_cu = NULL;
1347 const size_t num_objc_methods = method_die_infos.size();
1348 for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu)
1349 {
1350 method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx);
1351
1352 if (method_cu != prev_method_cu)
1353 method_cu->ExtractDIEsIfNeeded (false);
1354
1355 DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx);
1356
1357 ResolveType (method_cu, method_die);
1358 }
1359 }
1360 }
1361 }
1362
Greg Claytonc93237c2010-10-01 20:48:32 +00001363 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1364 // need to tell the clang type it is actually a class.
1365 if (class_language != eLanguageTypeObjC)
1366 {
1367 if (is_a_class && tag_decl_kind != clang::TTK_Class)
1368 type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class);
1369 }
1370
1371 // Since DW_TAG_structure_type gets used for both classes
1372 // and structures, we may need to set any DW_TAG_member
1373 // fields to have a "private" access if none was specified.
1374 // When we parsed the child members we tracked that actual
1375 // accessibility value for each DW_TAG_member in the
1376 // "member_accessibilities" array. If the value for the
1377 // member is zero, then it was set to the "default_accessibility"
1378 // which for structs was "public". Below we correct this
1379 // by setting any fields to "private" that weren't correctly
1380 // set.
1381 if (is_a_class && !member_accessibilities.empty())
1382 {
1383 // This is a class and all members that didn't have
1384 // their access specified are private.
1385 type_list->GetClangASTContext().SetDefaultAccessForRecordFields (clang_type, eAccessPrivate, &member_accessibilities.front(), member_accessibilities.size());
1386 }
1387
1388 if (!base_classes.empty())
1389 {
1390 type_list->GetClangASTContext().SetBaseClassesForClassType (clang_type, &base_classes.front(), base_classes.size());
1391
1392 // Clang will copy each CXXBaseSpecifier in "base_classes"
1393 // so we have to free them all.
1394 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(), base_classes.size());
1395 }
1396
1397 }
1398 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
1399 return clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001400
1401 case DW_TAG_enumeration_type:
1402 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
1403 if (die->HasChildren())
1404 {
1405 SymbolContext sc(GetCompUnitForDWARFCompUnit(cu));
1406 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), cu, die);
1407 }
1408 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
1409 return clang_type;
1410
1411 default:
1412 assert(false && "not a forward clang type decl!");
1413 break;
1414 }
1415 return NULL;
1416}
1417
Greg Claytonc685f8e2010-09-15 04:15:46 +00001418Type*
1419SymbolFileDWARF::ResolveType (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* type_die)
1420{
1421 if (type_die != NULL)
1422 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00001423 Type *type = m_die_to_type.lookup (type_die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001424 if (type == NULL)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001425 type = GetTypeForDIE (cu, type_die).get();
Greg Clayton594e5ed2010-09-27 21:07:38 +00001426 assert (type != DIE_IS_BEING_PARSED);
1427 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001428 }
1429 return NULL;
1430}
1431
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001432CompileUnit*
Greg Clayton0fffff52010-09-24 05:15:53 +00001433SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001434{
1435 // Check if the symbol vendor already knows about this compile unit?
1436 if (cu->GetUserData() == NULL)
1437 {
1438 // The symbol vendor doesn't know about this compile unit, we
1439 // need to parse and add it to the symbol vendor object.
1440 CompUnitSP dc_cu;
1441 ParseCompileUnit(cu, dc_cu);
1442 if (dc_cu.get())
1443 {
1444 // Figure out the compile unit index if we weren't given one
Greg Clayton016a95e2010-09-14 02:20:48 +00001445 if (cu_idx == UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001446 DebugInfo()->GetCompileUnit(cu->GetOffset(), &cu_idx);
1447
1448 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
Greg Clayton450e3f32010-10-12 02:24:53 +00001449
1450 if (m_debug_map_symfile)
1451 m_debug_map_symfile->SetCompileUnit(this, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001452 }
1453 }
1454 return (CompileUnit*)cu->GetUserData();
1455}
1456
1457bool
1458SymbolFileDWARF::GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
1459{
1460 sc.Clear();
1461 // Check if the symbol vendor already knows about this compile unit?
1462 sc.module_sp = m_obj_file->GetModule()->GetSP();
Greg Clayton016a95e2010-09-14 02:20:48 +00001463 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001464
1465 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1466 if (sc.function == NULL)
1467 sc.function = ParseCompileUnitFunction(sc, cu, func_die);
1468
1469 return sc.function != NULL;
1470}
1471
1472uint32_t
1473SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1474{
1475 Timer scoped_timer(__PRETTY_FUNCTION__,
1476 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1477 so_addr.GetSection(),
1478 so_addr.GetOffset(),
1479 resolve_scope);
1480 uint32_t resolved = 0;
1481 if (resolve_scope & ( eSymbolContextCompUnit |
1482 eSymbolContextFunction |
1483 eSymbolContextBlock |
1484 eSymbolContextLineEntry))
1485 {
1486 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1487
1488 DWARFDebugAranges* debug_aranges = DebugAranges();
1489 DWARFDebugInfo* debug_info = DebugInfo();
1490 if (debug_aranges)
1491 {
1492 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1493 if (cu_offset != DW_INVALID_OFFSET)
1494 {
1495 uint32_t cu_idx;
1496 DWARFCompileUnit* cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1497 if (cu)
1498 {
1499 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1500 assert(sc.comp_unit != NULL);
1501 resolved |= eSymbolContextCompUnit;
1502
1503 if (resolve_scope & eSymbolContextLineEntry)
1504 {
1505 LineTable *line_table = sc.comp_unit->GetLineTable();
1506 if (line_table == NULL)
1507 {
1508 if (ParseCompileUnitLineTable(sc))
1509 line_table = sc.comp_unit->GetLineTable();
1510 }
1511 if (line_table != NULL)
1512 {
1513 if (so_addr.IsLinkedAddress())
1514 {
1515 Address linked_addr (so_addr);
1516 linked_addr.ResolveLinkedAddress();
1517 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1518 {
1519 resolved |= eSymbolContextLineEntry;
1520 }
1521 }
1522 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1523 {
1524 resolved |= eSymbolContextLineEntry;
1525 }
1526 }
1527 }
1528
1529 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1530 {
1531 DWARFDebugInfoEntry *function_die = NULL;
1532 DWARFDebugInfoEntry *block_die = NULL;
1533 if (resolve_scope & eSymbolContextBlock)
1534 {
1535 cu->LookupAddress(file_vm_addr, &function_die, &block_die);
1536 }
1537 else
1538 {
1539 cu->LookupAddress(file_vm_addr, &function_die, NULL);
1540 }
1541
1542 if (function_die != NULL)
1543 {
1544 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1545 if (sc.function == NULL)
1546 sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1547 }
1548
1549 if (sc.function != NULL)
1550 {
1551 resolved |= eSymbolContextFunction;
1552
1553 if (resolve_scope & eSymbolContextBlock)
1554 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001555 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001556
1557 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001558 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001559 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001560 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001561 if (sc.block)
1562 resolved |= eSymbolContextBlock;
1563 }
1564 }
1565 }
1566 }
1567 }
1568 }
1569 }
1570 return resolved;
1571}
1572
1573
1574
1575uint32_t
1576SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1577{
1578 const uint32_t prev_size = sc_list.GetSize();
1579 if (resolve_scope & eSymbolContextCompUnit)
1580 {
1581 DWARFDebugInfo* debug_info = DebugInfo();
1582 if (debug_info)
1583 {
1584 uint32_t cu_idx;
1585 DWARFCompileUnit* cu = NULL;
1586
1587 for (cu_idx = 0; (cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
1588 {
1589 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1590 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1591 if (check_inlines || file_spec_matches_cu_file_spec)
1592 {
1593 SymbolContext sc (m_obj_file->GetModule());
1594 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1595 assert(sc.comp_unit != NULL);
1596
1597 uint32_t file_idx = UINT32_MAX;
1598
1599 // If we are looking for inline functions only and we don't
1600 // find it in the support files, we are done.
1601 if (check_inlines)
1602 {
1603 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1604 if (file_idx == UINT32_MAX)
1605 continue;
1606 }
1607
1608 if (line != 0)
1609 {
1610 LineTable *line_table = sc.comp_unit->GetLineTable();
1611
1612 if (line_table != NULL && line != 0)
1613 {
1614 // We will have already looked up the file index if
1615 // we are searching for inline entries.
1616 if (!check_inlines)
1617 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1618
1619 if (file_idx != UINT32_MAX)
1620 {
1621 uint32_t found_line;
1622 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1623 found_line = sc.line_entry.line;
1624
Greg Clayton016a95e2010-09-14 02:20:48 +00001625 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001626 {
1627 sc.function = NULL;
1628 sc.block = NULL;
1629 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1630 {
1631 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1632 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1633 {
1634 DWARFDebugInfoEntry *function_die = NULL;
1635 DWARFDebugInfoEntry *block_die = NULL;
1636 cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
1637
1638 if (function_die != NULL)
1639 {
1640 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1641 if (sc.function == NULL)
1642 sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1643 }
1644
1645 if (sc.function != NULL)
1646 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001647 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001648
1649 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001650 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001651 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001652 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001653 }
1654 }
1655 }
1656
1657 sc_list.Append(sc);
1658 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1659 }
1660 }
1661 }
1662 else if (file_spec_matches_cu_file_spec && !check_inlines)
1663 {
1664 // only append the context if we aren't looking for inline call sites
1665 // by file and line and if the file spec matches that of the compile unit
1666 sc_list.Append(sc);
1667 }
1668 }
1669 else if (file_spec_matches_cu_file_spec && !check_inlines)
1670 {
1671 // only append the context if we aren't looking for inline call sites
1672 // by file and line and if the file spec matches that of the compile unit
1673 sc_list.Append(sc);
1674 }
1675
1676 if (!check_inlines)
1677 break;
1678 }
1679 }
1680 }
1681 }
1682 return sc_list.GetSize() - prev_size;
1683}
1684
1685void
1686SymbolFileDWARF::Index ()
1687{
1688 if (m_indexed)
1689 return;
1690 m_indexed = true;
1691 Timer scoped_timer (__PRETTY_FUNCTION__,
1692 "SymbolFileDWARF::Index (%s)",
1693 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1694
1695 DWARFDebugInfo* debug_info = DebugInfo();
1696 if (debug_info)
1697 {
Greg Clayton016a95e2010-09-14 02:20:48 +00001698 m_aranges.reset(new DWARFDebugAranges());
1699
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001700 uint32_t cu_idx = 0;
1701 const uint32_t num_compile_units = GetNumCompileUnits();
1702 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1703 {
1704 DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
1705
1706 bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1;
1707
Greg Claytonc685f8e2010-09-15 04:15:46 +00001708 cu->Index (cu_idx,
1709 m_function_basename_index,
1710 m_function_fullname_index,
1711 m_function_method_index,
1712 m_function_selector_index,
Greg Clayton450e3f32010-10-12 02:24:53 +00001713 m_objc_class_selectors_index,
Greg Claytonc685f8e2010-09-15 04:15:46 +00001714 m_global_index,
1715 m_types_index,
Greg Clayton016a95e2010-09-14 02:20:48 +00001716 DebugRanges(),
1717 m_aranges.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001718
1719 // Keep memory down by clearing DIEs if this generate function
1720 // caused them to be parsed
1721 if (clear_dies)
1722 cu->ClearDIEs (true);
1723 }
1724
Greg Clayton016a95e2010-09-14 02:20:48 +00001725 m_aranges->Sort();
Greg Claytonc685f8e2010-09-15 04:15:46 +00001726
Greg Clayton450e3f32010-10-12 02:24:53 +00001727#if 0
Greg Claytonc685f8e2010-09-15 04:15:46 +00001728 StreamFile s(stdout);
1729 s.Printf("DWARF index for '%s':", GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1730 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
1731 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
1732 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
1733 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
Greg Clayton450e3f32010-10-12 02:24:53 +00001734 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001735 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
1736 s.Printf("\nTypes:\n"); m_types_index.Dump (&s);
1737#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001738 }
1739}
1740
1741uint32_t
1742SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1743{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001744 DWARFDebugInfo* info = DebugInfo();
1745 if (info == NULL)
1746 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001747
1748 // If we aren't appending the results to this list, then clear the list
1749 if (!append)
1750 variables.Clear();
1751
1752 // Remember how many variables are in the list before we search in case
1753 // we are appending the results to a variable list.
1754 const uint32_t original_size = variables.GetSize();
1755
1756 // Index the DWARF if we haven't already
1757 if (!m_indexed)
1758 Index ();
1759
Greg Claytonc685f8e2010-09-15 04:15:46 +00001760 SymbolContext sc;
1761 sc.module_sp = m_obj_file->GetModule()->GetSP();
1762 assert (sc.module_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001763
Greg Claytonc685f8e2010-09-15 04:15:46 +00001764 DWARFCompileUnit* cu = NULL;
1765 DWARFCompileUnit* prev_cu = NULL;
1766 const DWARFDebugInfoEntry* die = NULL;
1767 std::vector<NameToDIE::Info> die_info_array;
1768 const size_t num_matches = m_global_index.Find(name, die_info_array);
1769 for (size_t i=0; i<num_matches; ++i, prev_cu = cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001770 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001771 cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1772
1773 if (cu != prev_cu)
1774 cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001775
Greg Claytonc685f8e2010-09-15 04:15:46 +00001776 die = cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001777
Greg Claytonc685f8e2010-09-15 04:15:46 +00001778 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT32_MAX);
1779 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001780
Greg Claytonc685f8e2010-09-15 04:15:46 +00001781 ParseVariables(sc, cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
1782
1783 if (variables.GetSize() - original_size >= max_matches)
1784 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001785 }
1786
1787 // Return the number of variable that were appended to the list
1788 return variables.GetSize() - original_size;
1789}
1790
1791uint32_t
1792SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1793{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001794 DWARFDebugInfo* info = DebugInfo();
1795 if (info == NULL)
1796 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001797
1798 // If we aren't appending the results to this list, then clear the list
1799 if (!append)
1800 variables.Clear();
1801
1802 // Remember how many variables are in the list before we search in case
1803 // we are appending the results to a variable list.
1804 const uint32_t original_size = variables.GetSize();
1805
1806 // Index the DWARF if we haven't already
1807 if (!m_indexed)
1808 Index ();
1809
Greg Claytonc685f8e2010-09-15 04:15:46 +00001810 SymbolContext sc;
1811 sc.module_sp = m_obj_file->GetModule()->GetSP();
1812 assert (sc.module_sp);
1813
1814 DWARFCompileUnit* cu = NULL;
1815 DWARFCompileUnit* prev_cu = NULL;
1816 const DWARFDebugInfoEntry* die = NULL;
1817 std::vector<NameToDIE::Info> die_info_array;
1818 const size_t num_matches = m_global_index.Find(regex, die_info_array);
1819 for (size_t i=0; i<num_matches; ++i, prev_cu = cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001820 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001821 cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1822
1823 if (cu != prev_cu)
1824 cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001825
Greg Claytonc685f8e2010-09-15 04:15:46 +00001826 die = cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001827
Greg Claytonc685f8e2010-09-15 04:15:46 +00001828 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT32_MAX);
1829 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001830
Greg Claytonc685f8e2010-09-15 04:15:46 +00001831 ParseVariables(sc, cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001832
Greg Claytonc685f8e2010-09-15 04:15:46 +00001833 if (variables.GetSize() - original_size >= max_matches)
1834 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001835 }
1836
1837 // Return the number of variable that were appended to the list
1838 return variables.GetSize() - original_size;
1839}
1840
1841
Greg Clayton0c5cd902010-06-28 21:30:43 +00001842void
1843SymbolFileDWARF::FindFunctions
1844(
1845 const ConstString &name,
Greg Claytonc685f8e2010-09-15 04:15:46 +00001846 const NameToDIE &name_to_die,
Greg Clayton0c5cd902010-06-28 21:30:43 +00001847 SymbolContextList& sc_list
1848)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001849{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001850 DWARFDebugInfo* info = DebugInfo();
1851 if (info == NULL)
1852 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001853
Greg Claytonc685f8e2010-09-15 04:15:46 +00001854 SymbolContext sc;
1855 sc.module_sp = m_obj_file->GetModule()->GetSP();
1856 assert (sc.module_sp);
1857
1858 DWARFCompileUnit* cu = NULL;
1859 DWARFCompileUnit* prev_cu = NULL;
1860 const DWARFDebugInfoEntry* die = NULL;
1861 std::vector<NameToDIE::Info> die_info_array;
1862 const size_t num_matches = name_to_die.Find(name, die_info_array);
1863 for (size_t i=0; i<num_matches; ++i, prev_cu = cu)
1864 {
1865 cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1866
1867 if (cu != prev_cu)
1868 cu->ExtractDIEsIfNeeded (false);
1869
1870 die = cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
1871 if (GetFunction (cu, die, sc))
1872 {
1873 // We found the function, so we should find the line table
1874 // and line table entry as well
1875 LineTable *line_table = sc.comp_unit->GetLineTable();
1876 if (line_table == NULL)
1877 {
1878 if (ParseCompileUnitLineTable(sc))
1879 line_table = sc.comp_unit->GetLineTable();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001880 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00001881 if (line_table != NULL)
1882 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1883
1884 sc_list.Append(sc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001885 }
1886 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00001887}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001888
Greg Claytonc685f8e2010-09-15 04:15:46 +00001889
1890void
1891SymbolFileDWARF::FindFunctions
1892(
1893 const RegularExpression &regex,
1894 const NameToDIE &name_to_die,
1895 SymbolContextList& sc_list
1896)
1897{
1898 DWARFDebugInfo* info = DebugInfo();
1899 if (info == NULL)
1900 return;
1901
1902 SymbolContext sc;
1903 sc.module_sp = m_obj_file->GetModule()->GetSP();
1904 assert (sc.module_sp);
1905
1906 DWARFCompileUnit* cu = NULL;
1907 DWARFCompileUnit* prev_cu = NULL;
1908 const DWARFDebugInfoEntry* die = NULL;
1909 std::vector<NameToDIE::Info> die_info_array;
1910 const size_t num_matches = name_to_die.Find(regex, die_info_array);
1911 for (size_t i=0; i<num_matches; ++i, prev_cu = cu)
1912 {
1913 cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1914
1915 if (cu != prev_cu)
1916 cu->ExtractDIEsIfNeeded (false);
1917
1918 die = cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
1919 if (GetFunction (cu, die, sc))
1920 {
1921 // We found the function, so we should find the line table
1922 // and line table entry as well
1923 LineTable *line_table = sc.comp_unit->GetLineTable();
1924 if (line_table == NULL)
1925 {
1926 if (ParseCompileUnitLineTable(sc))
1927 line_table = sc.comp_unit->GetLineTable();
1928 }
1929 if (line_table != NULL)
1930 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1931
1932 sc_list.Append(sc);
1933 }
1934 }
Greg Clayton0c5cd902010-06-28 21:30:43 +00001935}
1936
1937uint32_t
1938SymbolFileDWARF::FindFunctions
1939(
1940 const ConstString &name,
1941 uint32_t name_type_mask,
1942 bool append,
1943 SymbolContextList& sc_list
1944)
1945{
1946 Timer scoped_timer (__PRETTY_FUNCTION__,
1947 "SymbolFileDWARF::FindFunctions (name = '%s')",
1948 name.AsCString());
1949
Greg Clayton0c5cd902010-06-28 21:30:43 +00001950 // If we aren't appending the results to this list, then clear the list
1951 if (!append)
1952 sc_list.Clear();
1953
1954 // Remember how many sc_list are in the list before we search in case
1955 // we are appending the results to a variable list.
1956 uint32_t original_size = sc_list.GetSize();
1957
1958 // Index the DWARF if we haven't already
1959 if (!m_indexed)
1960 Index ();
1961
1962 if (name_type_mask & eFunctionNameTypeBase)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001963 FindFunctions (name, m_function_basename_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00001964
1965 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001966 FindFunctions (name, m_function_fullname_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00001967
1968 if (name_type_mask & eFunctionNameTypeMethod)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001969 FindFunctions (name, m_function_method_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00001970
1971 if (name_type_mask & eFunctionNameTypeSelector)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001972 FindFunctions (name, m_function_selector_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00001973
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001974 // Return the number of variable that were appended to the list
1975 return sc_list.GetSize() - original_size;
1976}
1977
1978
1979uint32_t
1980SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
1981{
1982 Timer scoped_timer (__PRETTY_FUNCTION__,
1983 "SymbolFileDWARF::FindFunctions (regex = '%s')",
1984 regex.GetText());
1985
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001986 // If we aren't appending the results to this list, then clear the list
1987 if (!append)
1988 sc_list.Clear();
1989
1990 // Remember how many sc_list are in the list before we search in case
1991 // we are appending the results to a variable list.
1992 uint32_t original_size = sc_list.GetSize();
1993
1994 // Index the DWARF if we haven't already
1995 if (!m_indexed)
1996 Index ();
1997
Greg Claytonc685f8e2010-09-15 04:15:46 +00001998 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001999
Greg Claytonc685f8e2010-09-15 04:15:46 +00002000 FindFunctions (regex, m_function_fullname_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002001
2002 // Return the number of variable that were appended to the list
2003 return sc_list.GetSize() - original_size;
2004}
2005
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002006uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002007SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002008{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002009 DWARFDebugInfo* info = DebugInfo();
2010 if (info == NULL)
2011 return 0;
2012
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002013 // If we aren't appending the results to this list, then clear the list
2014 if (!append)
2015 types.Clear();
2016
Greg Clayton6dbd3982010-09-15 05:51:24 +00002017 // Index if we already haven't to make sure the compile units
2018 // get indexed and make their global DIE index list
2019 if (!m_indexed)
2020 Index ();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002021
Greg Claytonc685f8e2010-09-15 04:15:46 +00002022 const uint32_t initial_types_size = types.GetSize();
2023 DWARFCompileUnit* cu = NULL;
2024 DWARFCompileUnit* prev_cu = NULL;
2025 const DWARFDebugInfoEntry* die = NULL;
2026 std::vector<NameToDIE::Info> die_info_array;
2027 const size_t num_matches = m_types_index.Find (name, die_info_array);
2028 for (size_t i=0; i<num_matches; ++i, prev_cu = cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002029 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00002030 cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2031
2032 if (cu != prev_cu)
2033 cu->ExtractDIEsIfNeeded (false);
2034
2035 die = cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2036
2037 Type *matching_type = ResolveType (cu, die);
2038 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002039 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00002040 // We found a type pointer, now find the shared pointer form our type list
2041 TypeSP type_sp (m_obj_file->GetModule()->GetTypeList()->FindType(matching_type->GetID()));
2042 assert (type_sp.get() != NULL);
2043 types.InsertUnique (type_sp);
2044 if (types.GetSize() >= max_matches)
2045 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002046 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002047 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002048 return types.GetSize() - initial_types_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002049}
2050
2051
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002052uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002053SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002054{
2055 // Remember how many sc_list are in the list before we search in case
2056 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002057 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002058
2059 const uint32_t num_die_offsets = die_offsets.size();
2060 // Parse all of the types we found from the pubtypes matches
2061 uint32_t i;
2062 uint32_t num_matches = 0;
2063 for (i = 0; i < num_die_offsets; ++i)
2064 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002065 Type *matching_type = ResolveTypeUID (die_offsets[i]);
2066 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002067 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002068 // We found a type pointer, now find the shared pointer form our type list
2069 TypeSP type_sp (m_obj_file->GetModule()->GetTypeList()->FindType(matching_type->GetID()));
2070 assert (type_sp.get() != NULL);
2071 types.InsertUnique (type_sp);
2072 ++num_matches;
2073 if (num_matches >= max_matches)
2074 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002075 }
2076 }
2077
2078 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002079 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002080}
2081
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002082
2083size_t
2084SymbolFileDWARF::ParseChildParameters
2085(
2086 const SymbolContext& sc,
2087 TypeSP& type_sp,
Greg Clayton0fffff52010-09-24 05:15:53 +00002088 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002089 const DWARFDebugInfoEntry *parent_die,
Greg Claytona51ed9b2010-09-23 01:09:21 +00002090 bool skip_artificial,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002091 TypeList* type_list,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002092 std::vector<clang_type_t>& function_param_types,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002093 std::vector<clang::ParmVarDecl*>& function_param_decls
2094)
2095{
2096 if (parent_die == NULL)
2097 return 0;
2098
Greg Claytond88d7592010-09-15 08:33:30 +00002099 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2100
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002101 size_t count = 0;
2102 const DWARFDebugInfoEntry *die;
2103 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2104 {
2105 dw_tag_t tag = die->Tag();
2106 switch (tag)
2107 {
2108 case DW_TAG_formal_parameter:
2109 {
2110 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002111 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002112 if (num_attributes > 0)
2113 {
2114 const char *name = NULL;
2115 Declaration decl;
2116 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002117 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002118 // one of None, Auto, Register, Extern, Static, PrivateExtern
2119
Sean Callanane2ef6e32010-09-23 03:01:22 +00002120 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002121 uint32_t i;
2122 for (i=0; i<num_attributes; ++i)
2123 {
2124 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2125 DWARFFormValue form_value;
2126 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2127 {
2128 switch (attr)
2129 {
2130 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2131 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2132 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2133 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2134 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002135 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002136 case DW_AT_location:
2137 // if (form_value.BlockData())
2138 // {
2139 // const DataExtractor& debug_info_data = debug_info();
2140 // uint32_t block_length = form_value.Unsigned();
2141 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2142 // }
2143 // else
2144 // {
2145 // }
2146 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002147 case DW_AT_const_value:
2148 case DW_AT_default_value:
2149 case DW_AT_description:
2150 case DW_AT_endianity:
2151 case DW_AT_is_optional:
2152 case DW_AT_segment:
2153 case DW_AT_variable_parameter:
2154 default:
2155 case DW_AT_abstract_origin:
2156 case DW_AT_sibling:
2157 break;
2158 }
2159 }
2160 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00002161
Greg Clayton0fffff52010-09-24 05:15:53 +00002162 bool skip = false;
2163 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002164 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002165 if (is_artificial)
2166 skip = true;
2167 else
2168 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002169
Greg Clayton0fffff52010-09-24 05:15:53 +00002170 // HACK: Objective C formal parameters "self" and "_cmd"
2171 // are not marked as artificial in the DWARF...
2172 CompileUnit *cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2173 if (cu && (cu->GetLanguage() == eLanguageTypeObjC || cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
2174 {
2175 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2176 skip = true;
2177 }
2178 }
2179 }
2180
2181 if (!skip)
2182 {
2183 Type *type = ResolveTypeUID(param_type_die_offset);
2184 if (type)
2185 {
Greg Claytonc93237c2010-10-01 20:48:32 +00002186 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00002187
Greg Claytonc93237c2010-10-01 20:48:32 +00002188 clang::ParmVarDecl *param_var_decl = type_list->GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00002189 assert(param_var_decl);
2190 function_param_decls.push_back(param_var_decl);
2191 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002192 }
2193 }
2194 }
2195 break;
2196
2197 default:
2198 break;
2199 }
2200 }
2201 return count;
2202}
2203
2204size_t
2205SymbolFileDWARF::ParseChildEnumerators
2206(
2207 const SymbolContext& sc,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002208 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002209 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00002210 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002211 const DWARFDebugInfoEntry *parent_die
2212)
2213{
2214 if (parent_die == NULL)
2215 return 0;
2216
2217 size_t enumerators_added = 0;
2218 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002219 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2220
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002221 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2222 {
2223 const dw_tag_t tag = die->Tag();
2224 if (tag == DW_TAG_enumerator)
2225 {
2226 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002227 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002228 if (num_child_attributes > 0)
2229 {
2230 const char *name = NULL;
2231 bool got_value = false;
2232 int64_t enum_value = 0;
2233 Declaration decl;
2234
2235 uint32_t i;
2236 for (i=0; i<num_child_attributes; ++i)
2237 {
2238 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2239 DWARFFormValue form_value;
2240 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2241 {
2242 switch (attr)
2243 {
2244 case DW_AT_const_value:
2245 got_value = true;
2246 enum_value = form_value.Unsigned();
2247 break;
2248
2249 case DW_AT_name:
2250 name = form_value.AsCString(&get_debug_str_data());
2251 break;
2252
2253 case DW_AT_description:
2254 default:
2255 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2256 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2257 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2258 case DW_AT_sibling:
2259 break;
2260 }
2261 }
2262 }
2263
2264 if (name && name[0] && got_value)
2265 {
2266 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
Greg Clayton1be10fc2010-09-29 01:12:09 +00002267 type_list->GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2268 enumerator_clang_type,
2269 decl,
2270 name,
2271 enum_value,
2272 enumerator_byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002273 ++enumerators_added;
2274 }
2275 }
2276 }
2277 }
2278 return enumerators_added;
2279}
2280
2281void
2282SymbolFileDWARF::ParseChildArrayInfo
2283(
2284 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00002285 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002286 const DWARFDebugInfoEntry *parent_die,
2287 int64_t& first_index,
2288 std::vector<uint64_t>& element_orders,
2289 uint32_t& byte_stride,
2290 uint32_t& bit_stride
2291)
2292{
2293 if (parent_die == NULL)
2294 return;
2295
2296 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002297 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002298 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2299 {
2300 const dw_tag_t tag = die->Tag();
2301 switch (tag)
2302 {
2303 case DW_TAG_enumerator:
2304 {
2305 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002306 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002307 if (num_child_attributes > 0)
2308 {
2309 const char *name = NULL;
2310 bool got_value = false;
2311 int64_t enum_value = 0;
2312
2313 uint32_t i;
2314 for (i=0; i<num_child_attributes; ++i)
2315 {
2316 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2317 DWARFFormValue form_value;
2318 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2319 {
2320 switch (attr)
2321 {
2322 case DW_AT_const_value:
2323 got_value = true;
2324 enum_value = form_value.Unsigned();
2325 break;
2326
2327 case DW_AT_name:
2328 name = form_value.AsCString(&get_debug_str_data());
2329 break;
2330
2331 case DW_AT_description:
2332 default:
2333 case DW_AT_decl_file:
2334 case DW_AT_decl_line:
2335 case DW_AT_decl_column:
2336 case DW_AT_sibling:
2337 break;
2338 }
2339 }
2340 }
2341 }
2342 }
2343 break;
2344
2345 case DW_TAG_subrange_type:
2346 {
2347 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002348 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002349 if (num_child_attributes > 0)
2350 {
2351 const char *name = NULL;
2352 bool got_value = false;
2353 uint64_t byte_size = 0;
2354 int64_t enum_value = 0;
2355 uint64_t num_elements = 0;
2356 uint64_t lower_bound = 0;
2357 uint64_t upper_bound = 0;
2358 uint32_t i;
2359 for (i=0; i<num_child_attributes; ++i)
2360 {
2361 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2362 DWARFFormValue form_value;
2363 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2364 {
2365 switch (attr)
2366 {
2367 case DW_AT_const_value:
2368 got_value = true;
2369 enum_value = form_value.Unsigned();
2370 break;
2371
2372 case DW_AT_name:
2373 name = form_value.AsCString(&get_debug_str_data());
2374 break;
2375
2376 case DW_AT_count:
2377 num_elements = form_value.Unsigned();
2378 break;
2379
2380 case DW_AT_bit_stride:
2381 bit_stride = form_value.Unsigned();
2382 break;
2383
2384 case DW_AT_byte_stride:
2385 byte_stride = form_value.Unsigned();
2386 break;
2387
2388 case DW_AT_byte_size:
2389 byte_size = form_value.Unsigned();
2390 break;
2391
2392 case DW_AT_lower_bound:
2393 lower_bound = form_value.Unsigned();
2394 break;
2395
2396 case DW_AT_upper_bound:
2397 upper_bound = form_value.Unsigned();
2398 break;
2399
2400 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002401 case DW_AT_abstract_origin:
2402 case DW_AT_accessibility:
2403 case DW_AT_allocated:
2404 case DW_AT_associated:
2405 case DW_AT_data_location:
2406 case DW_AT_declaration:
2407 case DW_AT_description:
2408 case DW_AT_sibling:
2409 case DW_AT_threads_scaled:
2410 case DW_AT_type:
2411 case DW_AT_visibility:
2412 break;
2413 }
2414 }
2415 }
2416
2417 if (upper_bound > lower_bound)
2418 num_elements = upper_bound - lower_bound + 1;
2419
2420 if (num_elements > 0)
2421 element_orders.push_back (num_elements);
2422 }
2423 }
2424 break;
2425 }
2426 }
2427}
2428
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002429TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00002430SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002431{
2432 TypeSP type_sp;
2433 if (die != NULL)
2434 {
2435 assert(cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00002436 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002437 if (type_ptr == NULL)
2438 {
2439 SymbolContext sc(GetCompUnitForDWARFCompUnit(cu));
Greg Clayton1be10fc2010-09-29 01:12:09 +00002440 type_sp = ParseType(sc, cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002441 }
2442 else if (type_ptr != DIE_IS_BEING_PARSED)
2443 {
2444 // Grab the existing type from the master types lists
2445 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(type_ptr->GetID());
2446 }
2447
2448 }
2449 return type_sp;
2450}
2451
2452clang::DeclContext *
2453SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2454{
2455 if (die_offset != DW_INVALID_OFFSET)
2456 {
2457 DWARFCompileUnitSP cu_sp;
2458 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2459 return GetClangDeclContextForDIE (cu_sp.get(), die);
2460 }
2461 return NULL;
2462}
2463
2464
2465
2466clang::DeclContext *
Greg Clayton0fffff52010-09-24 05:15:53 +00002467SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002468{
2469 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2470 if (pos != m_die_to_decl_ctx.end())
2471 return pos->second;
2472
2473 while (die != NULL)
2474 {
2475 switch (die->Tag())
2476 {
2477 case DW_TAG_namespace:
2478 {
2479 const char *namespace_name = die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL);
2480 if (namespace_name)
2481 {
2482 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2483 assert(type_list);
2484 Declaration decl; // TODO: fill in the decl object
2485 clang::NamespaceDecl *namespace_decl = type_list->GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (cu, die->GetParent()));
2486 if (namespace_decl)
2487 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2488 return namespace_decl;
2489 }
2490 }
2491 break;
2492
2493 default:
2494 break;
2495 }
2496 clang::DeclContext *decl_ctx;
2497 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_specification, DW_INVALID_OFFSET));
2498 if (decl_ctx)
2499 return decl_ctx;
2500
2501 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET));
2502 if (decl_ctx)
2503 return decl_ctx;
2504
2505 die = die->GetParent();
2506 }
2507 return NULL;
2508}
2509
2510TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00002511SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002512{
2513 TypeSP type_sp;
2514
Greg Clayton1be10fc2010-09-29 01:12:09 +00002515 if (type_is_new_ptr)
2516 *type_is_new_ptr = false;
2517
Sean Callananc7fbf732010-08-06 00:32:49 +00002518 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002519 if (die != NULL)
2520 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00002521 Type *type_ptr = m_die_to_type.lookup (die);
2522 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002523 {
Greg Clayton1be10fc2010-09-29 01:12:09 +00002524 if (type_is_new_ptr)
2525 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002526
Greg Clayton594e5ed2010-09-27 21:07:38 +00002527 const dw_tag_t tag = die->Tag();
2528
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002529 bool is_forward_declaration = false;
2530 DWARFDebugInfoEntry::Attributes attributes;
2531 const char *type_name_cstr = NULL;
2532 ConstString type_name_dbstr;
Greg Clayton4957bf62010-09-30 21:49:03 +00002533 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002534 clang_type_t clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002535
2536 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2537 dw_attr_t attr;
2538
2539 switch (tag)
2540 {
2541 case DW_TAG_base_type:
2542 case DW_TAG_pointer_type:
2543 case DW_TAG_reference_type:
2544 case DW_TAG_typedef:
2545 case DW_TAG_const_type:
2546 case DW_TAG_restrict_type:
2547 case DW_TAG_volatile_type:
2548 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002549 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002550 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002551
Greg Claytond88d7592010-09-15 08:33:30 +00002552 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002553 Declaration decl;
2554 uint32_t encoding = 0;
2555 size_t byte_size = 0;
2556 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
2557
2558 if (num_attributes > 0)
2559 {
2560 uint32_t i;
2561 for (i=0; i<num_attributes; ++i)
2562 {
2563 attr = attributes.AttributeAtIndex(i);
2564 DWARFFormValue form_value;
2565 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2566 {
2567 switch (attr)
2568 {
2569 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2570 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2571 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2572 case DW_AT_name:
2573 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2574 type_name_dbstr.SetCString(type_name_cstr);
2575 break;
2576 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
2577 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
2578 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2579 default:
2580 case DW_AT_sibling:
2581 break;
2582 }
2583 }
2584 }
2585 }
2586
Greg Claytonc93237c2010-10-01 20:48:32 +00002587 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") type => 0x%8.8x\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
2588
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002589 switch (tag)
2590 {
2591 default:
2592 case DW_TAG_base_type:
2593 clang_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, encoding, byte_size * 8);
2594 break;
2595
2596 case DW_TAG_pointer_type:
2597 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002598 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002599 encoding_data_type = Type::eEncodingIsPointerUID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002600 break;
2601
2602 case DW_TAG_reference_type:
2603 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002604 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002605 encoding_data_type = Type::eEncodingIsLValueReferenceUID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002606 break;
2607
2608 case DW_TAG_typedef:
2609 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002610 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002611 encoding_data_type = Type::eEncodingIsTypedefUID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002612 break;
2613
2614 case DW_TAG_const_type:
2615 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002616 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002617 encoding_data_type = Type::eEncodingIsConstUID; //ClangASTContext::AddConstModifier (clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002618 break;
2619
2620 case DW_TAG_restrict_type:
2621 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002622 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002623 encoding_data_type = Type::eEncodingIsRestrictUID; //ClangASTContext::AddRestrictModifier (clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002624 break;
2625
2626 case DW_TAG_volatile_type:
2627 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002628 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002629 encoding_data_type = Type::eEncodingIsVolatileUID; //ClangASTContext::AddVolatileModifier (clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002630 break;
2631 }
2632
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002633 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
2634 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
2635 {
2636 static ConstString g_objc_type_name_id("id");
2637 static ConstString g_objc_type_name_Class("Class");
2638 static ConstString g_objc_type_name_selector("SEL");
2639
2640 if (type_name_dbstr == g_objc_type_name_id)
2641 {
2642 clang_type = type_list->GetClangASTContext().GetBuiltInType_objc_id();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002643 }
2644 else if (type_name_dbstr == g_objc_type_name_Class)
2645 {
2646 clang_type = type_list->GetClangASTContext().GetBuiltInType_objc_Class();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002647 }
2648 else if (type_name_dbstr == g_objc_type_name_selector)
2649 {
2650 clang_type = type_list->GetClangASTContext().GetBuiltInType_objc_selector();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002651 }
2652 }
2653
Greg Clayton4957bf62010-09-30 21:49:03 +00002654 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, encoding_data_type, &decl, clang_type, clang_type == NULL));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002655
Greg Clayton594e5ed2010-09-27 21:07:38 +00002656 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002657
2658// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
2659// if (encoding_type != NULL)
2660// {
2661// if (encoding_type != DIE_IS_BEING_PARSED)
2662// type_sp->SetEncodingType(encoding_type);
2663// else
2664// m_indirect_fixups.push_back(type_sp.get());
2665// }
2666 }
2667 break;
2668
2669 case DW_TAG_structure_type:
2670 case DW_TAG_union_type:
2671 case DW_TAG_class_type:
2672 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002673 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002674 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002675
2676 size_t byte_size = 0;
Greg Clayton9e409562010-07-28 02:04:09 +00002677 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002678 //bool struct_is_class = false;
2679 Declaration decl;
Greg Claytond88d7592010-09-15 08:33:30 +00002680 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002681 if (num_attributes > 0)
2682 {
2683 uint32_t i;
2684 for (i=0; i<num_attributes; ++i)
2685 {
2686 attr = attributes.AttributeAtIndex(i);
2687 DWARFFormValue form_value;
2688 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2689 {
2690 switch (attr)
2691 {
Greg Clayton9e409562010-07-28 02:04:09 +00002692 case DW_AT_decl_file:
2693 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
2694 break;
2695
2696 case DW_AT_decl_line:
2697 decl.SetLine(form_value.Unsigned());
2698 break;
2699
2700 case DW_AT_decl_column:
2701 decl.SetColumn(form_value.Unsigned());
2702 break;
2703
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002704 case DW_AT_name:
2705 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2706 type_name_dbstr.SetCString(type_name_cstr);
2707 break;
Greg Clayton9e409562010-07-28 02:04:09 +00002708
2709 case DW_AT_byte_size:
2710 byte_size = form_value.Unsigned();
2711 break;
2712
2713 case DW_AT_accessibility:
2714 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
2715 break;
2716
2717 case DW_AT_declaration:
2718 is_forward_declaration = form_value.Unsigned() != 0;
2719 break;
2720
2721 case DW_AT_APPLE_runtime_class:
2722 class_language = (LanguageType)form_value.Signed();
2723 break;
2724
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002725 case DW_AT_allocated:
2726 case DW_AT_associated:
2727 case DW_AT_data_location:
2728 case DW_AT_description:
2729 case DW_AT_start_scope:
2730 case DW_AT_visibility:
2731 default:
2732 case DW_AT_sibling:
2733 break;
2734 }
2735 }
2736 }
2737 }
2738
Greg Claytonc93237c2010-10-01 20:48:32 +00002739 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
2740
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002741 int tag_decl_kind = -1;
Sean Callananc7fbf732010-08-06 00:32:49 +00002742 AccessType default_accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002743 if (tag == DW_TAG_structure_type)
2744 {
2745 tag_decl_kind = clang::TTK_Struct;
Sean Callananc7fbf732010-08-06 00:32:49 +00002746 default_accessibility = eAccessPublic;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002747 }
2748 else if (tag == DW_TAG_union_type)
2749 {
2750 tag_decl_kind = clang::TTK_Union;
Sean Callananc7fbf732010-08-06 00:32:49 +00002751 default_accessibility = eAccessPublic;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002752 }
2753 else if (tag == DW_TAG_class_type)
2754 {
2755 tag_decl_kind = clang::TTK_Class;
Sean Callananc7fbf732010-08-06 00:32:49 +00002756 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002757 }
2758
2759 assert (tag_decl_kind != -1);
Greg Clayton1be10fc2010-09-29 01:12:09 +00002760 bool clang_type_was_created = false;
2761 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
2762 if (clang_type == NULL)
2763 {
2764 clang_type_was_created = true;
2765 clang_type = type_list->GetClangASTContext().CreateRecordType (type_name_cstr, tag_decl_kind, GetClangDeclContextForDIE (dwarf_cu, die), class_language);
2766 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002767
Greg Clayton6adffa22010-09-28 01:04:25 +00002768 // Store a forward declaration to this class type in case any
2769 // parameters in any class methods need it for the clang
2770 // types for function prototypes.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002771 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
Greg Clayton16c880f2010-09-30 22:25:09 +00002772 const bool is_forward_decl = die->HasChildren();
2773 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, clang_type, is_forward_decl));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002774
Greg Clayton594e5ed2010-09-27 21:07:38 +00002775 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002776
Greg Clayton4957bf62010-09-30 21:49:03 +00002777 if (die->HasChildren() == false)
Greg Clayton1be10fc2010-09-29 01:12:09 +00002778 {
Greg Clayton4957bf62010-09-30 21:49:03 +00002779 // No children for this struct/union/class, lets finish it
2780 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
2781 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
2782 }
2783 else if (clang_type_was_created)
2784 {
2785 // Leave this as a forward declaration until we need
2786 // to know the details of the type. lldb_private::Type
2787 // will automatically call the SymbolFile virtual function
2788 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
2789 // When the definition needs to be defined.
Greg Clayton1be10fc2010-09-29 01:12:09 +00002790 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00002791 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002792 }
Greg Clayton4957bf62010-09-30 21:49:03 +00002793
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002794 }
2795 break;
2796
2797 case DW_TAG_enumeration_type:
2798 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002799 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002800 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002801
2802 size_t byte_size = 0;
2803 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
2804 Declaration decl;
2805
Greg Claytond88d7592010-09-15 08:33:30 +00002806 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002807 if (num_attributes > 0)
2808 {
2809 uint32_t i;
2810
2811 for (i=0; i<num_attributes; ++i)
2812 {
2813 attr = attributes.AttributeAtIndex(i);
2814 DWARFFormValue form_value;
2815 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2816 {
2817 switch (attr)
2818 {
2819 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2820 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2821 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2822 case DW_AT_name:
2823 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2824 type_name_dbstr.SetCString(type_name_cstr);
2825 break;
2826 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2827 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00002828 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002829 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
2830 case DW_AT_allocated:
2831 case DW_AT_associated:
2832 case DW_AT_bit_stride:
2833 case DW_AT_byte_stride:
2834 case DW_AT_data_location:
2835 case DW_AT_description:
2836 case DW_AT_start_scope:
2837 case DW_AT_visibility:
2838 case DW_AT_specification:
2839 case DW_AT_abstract_origin:
2840 case DW_AT_sibling:
2841 break;
2842 }
2843 }
2844 }
2845
Greg Claytonc93237c2010-10-01 20:48:32 +00002846 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
2847
Greg Clayton1be10fc2010-09-29 01:12:09 +00002848 clang_type_t enumerator_clang_type = NULL;
2849 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
2850 if (clang_type == NULL)
2851 {
2852 enumerator_clang_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, DW_ATE_signed, byte_size * 8);
2853 clang_type = type_list->GetClangASTContext().CreateEnumerationType(decl, type_name_cstr, enumerator_clang_type);
2854 }
2855 else
2856 {
2857 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
2858 assert (enumerator_clang_type != NULL);
2859 }
2860
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002861 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
Greg Clayton4957bf62010-09-30 21:49:03 +00002862 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, Type::eEncodingIsUID, &decl, clang_type, true));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002863
Greg Clayton594e5ed2010-09-27 21:07:38 +00002864 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002865
Greg Clayton1be10fc2010-09-29 01:12:09 +00002866 // Leave this as a forward declaration until we need
2867 // to know the details of the type. lldb_private::Type
2868 // will automatically call the SymbolFile virtual function
2869 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
2870 // When the definition needs to be defined.
2871 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00002872 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002873
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002874 }
2875 }
2876 break;
2877
Jim Inghamb0be4422010-08-12 01:20:14 +00002878 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002879 case DW_TAG_subprogram:
2880 case DW_TAG_subroutine_type:
2881 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002882 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002883 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002884
2885 const char *mangled = NULL;
2886 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
2887 Declaration decl;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002888 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002889 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00002890 bool is_static = false;
2891 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00002892 bool is_explicit = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00002893
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002894 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00002895 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002896
2897
Greg Claytond88d7592010-09-15 08:33:30 +00002898 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002899 if (num_attributes > 0)
2900 {
2901 uint32_t i;
2902 for (i=0; i<num_attributes; ++i)
2903 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002904 const dw_attr_t attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002905 DWARFFormValue form_value;
2906 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2907 {
2908 switch (attr)
2909 {
2910 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2911 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2912 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2913 case DW_AT_name:
2914 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2915 type_name_dbstr.SetCString(type_name_cstr);
2916 break;
2917
2918 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
2919 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00002920 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002921 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00002922 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
2923 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Claytonf51de672010-10-01 02:31:07 +00002924 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
2925
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002926 case DW_AT_external:
2927 if (form_value.Unsigned())
2928 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00002929 if (storage == clang::SC_None)
2930 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002931 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00002932 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002933 }
2934 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002935
2936 case DW_AT_allocated:
2937 case DW_AT_associated:
2938 case DW_AT_address_class:
2939 case DW_AT_artificial:
2940 case DW_AT_calling_convention:
2941 case DW_AT_data_location:
2942 case DW_AT_elemental:
2943 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002944 case DW_AT_frame_base:
2945 case DW_AT_high_pc:
2946 case DW_AT_low_pc:
2947 case DW_AT_object_pointer:
2948 case DW_AT_prototyped:
2949 case DW_AT_pure:
2950 case DW_AT_ranges:
2951 case DW_AT_recursive:
2952 case DW_AT_return_addr:
2953 case DW_AT_segment:
2954 case DW_AT_specification:
2955 case DW_AT_start_scope:
2956 case DW_AT_static_link:
2957 case DW_AT_trampoline:
2958 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002959 case DW_AT_vtable_elem_location:
2960 case DW_AT_abstract_origin:
2961 case DW_AT_description:
2962 case DW_AT_sibling:
2963 break;
2964 }
2965 }
2966 }
2967
Greg Claytonc93237c2010-10-01 20:48:32 +00002968 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
2969
Greg Clayton1be10fc2010-09-29 01:12:09 +00002970 clang_type_t return_clang_type = NULL;
Greg Claytonf51de672010-10-01 02:31:07 +00002971 Type *func_type = NULL;
2972
2973 if (type_die_offset != DW_INVALID_OFFSET)
2974 func_type = ResolveTypeUID(type_die_offset);
2975
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002976 if (func_type)
Greg Claytonc93237c2010-10-01 20:48:32 +00002977 return_clang_type = func_type->GetClangForwardType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002978 else
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002979 return_clang_type = type_list->GetClangASTContext().GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002980
Greg Claytonf51de672010-10-01 02:31:07 +00002981
Greg Clayton1be10fc2010-09-29 01:12:09 +00002982 std::vector<clang_type_t> function_param_types;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002983 std::vector<clang::ParmVarDecl*> function_param_decls;
2984
2985 // Parse the function children for the parameters
Greg Clayton0fffff52010-09-24 05:15:53 +00002986 bool skip_artificial = true;
2987 ParseChildParameters (sc, type_sp, dwarf_cu, die, skip_artificial, type_list, function_param_types, function_param_decls);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002988
Greg Clayton0fffff52010-09-24 05:15:53 +00002989 // clang_type will get the function prototype clang type after this call
Greg Claytona51ed9b2010-09-23 01:09:21 +00002990 clang_type = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), is_variadic, type_quals);
Greg Claytonf51de672010-10-01 02:31:07 +00002991
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002992 if (type_name_cstr)
2993 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002994 bool type_handled = false;
2995 const DWARFDebugInfoEntry *parent_die = die->GetParent();
2996 if (tag == DW_TAG_subprogram)
2997 {
2998 if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+'))
2999 {
3000 // We need to find the DW_TAG_class_type or
3001 // DW_TAG_struct_type by name so we can add this
3002 // as a member function of the class.
3003 const char *class_name_start = type_name_cstr + 2;
3004 const char *class_name_end = ::strchr (class_name_start, ' ');
3005 SymbolContext empty_sc;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003006 clang_type_t class_opaque_type = NULL;
Greg Clayton0fffff52010-09-24 05:15:53 +00003007 if (class_name_start < class_name_end)
3008 {
3009 ConstString class_name (class_name_start, class_name_end - class_name_start);
3010 TypeList types;
3011 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
3012 if (match_count > 0)
3013 {
3014 for (uint32_t i=0; i<match_count; ++i)
3015 {
3016 Type *type = types.GetTypeAtIndex (i).get();
Greg Clayton450e3f32010-10-12 02:24:53 +00003017 clang_type_t type_clang_forward_type = type->GetClangForwardType();
3018 if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003019 {
Greg Clayton450e3f32010-10-12 02:24:53 +00003020 class_opaque_type = type_clang_forward_type;
Greg Clayton0fffff52010-09-24 05:15:53 +00003021 break;
3022 }
3023 }
3024 }
3025 }
3026
3027 if (class_opaque_type)
3028 {
Greg Clayton6d01ad92010-09-29 01:57:37 +00003029 // If accessibility isn't set to anything valid, assume public for
3030 // now...
3031 if (accessibility == eAccessNone)
3032 accessibility = eAccessPublic;
3033
Greg Clayton0fffff52010-09-24 05:15:53 +00003034 clang::ObjCMethodDecl *objc_method_decl;
3035 objc_method_decl = type_list->GetClangASTContext().AddMethodToObjCObjectType (class_opaque_type,
3036 type_name_cstr,
3037 clang_type,
3038 accessibility);
3039 type_handled = objc_method_decl != NULL;
3040 }
3041 }
3042 else if (parent_die->Tag() == DW_TAG_class_type ||
3043 parent_die->Tag() == DW_TAG_structure_type)
3044 {
3045 // Look at the parent of this DIE and see if is is
3046 // a class or struct and see if this is actually a
3047 // C++ method
3048 Type *class_type = ResolveType (dwarf_cu, parent_die);
3049 if (class_type)
3050 {
Greg Claytonc93237c2010-10-01 20:48:32 +00003051 clang_type_t class_opaque_type = class_type->GetClangForwardType();
Greg Clayton0fffff52010-09-24 05:15:53 +00003052 if (ClangASTContext::IsCXXClassType (class_opaque_type))
3053 {
Greg Clayton6d01ad92010-09-29 01:57:37 +00003054 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
3055 // in the DWARF for C++ methods... Default to public for now...
3056 if (accessibility == eAccessNone)
3057 accessibility = eAccessPublic;
3058
Greg Clayton0fffff52010-09-24 05:15:53 +00003059 clang::CXXMethodDecl *cxx_method_decl;
3060 cxx_method_decl = type_list->GetClangASTContext().AddMethodToCXXRecordType (class_opaque_type,
3061 type_name_cstr,
3062 clang_type,
3063 accessibility,
3064 is_virtual,
3065 is_static,
Greg Claytonf51de672010-10-01 02:31:07 +00003066 is_inline,
3067 is_explicit);
Greg Clayton0fffff52010-09-24 05:15:53 +00003068 type_handled = cxx_method_decl != NULL;
3069 }
3070 }
3071 }
3072 }
3073
3074 if (!type_handled)
3075 {
3076 // We just have a function that isn't part of a class
3077 clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline);
3078
3079 // Add the decl to our DIE to decl context map
3080 assert (function_decl);
3081 m_die_to_decl_ctx[die] = function_decl;
3082 if (!function_param_decls.empty())
3083 type_list->GetClangASTContext().SetFunctionParameters (function_decl, &function_param_decls.front(), function_param_decls.size());
3084 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003085 }
Greg Clayton4957bf62010-09-30 21:49:03 +00003086 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, 0, NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, clang_type, false));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003087
Greg Clayton594e5ed2010-09-27 21:07:38 +00003088 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003089 assert(type_sp.get());
3090 }
3091 }
3092 break;
3093
3094 case DW_TAG_array_type:
3095 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003096 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003097 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003098
3099 size_t byte_size = 0;
3100 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
3101 Declaration decl;
3102 int64_t first_index = 0;
3103 uint32_t byte_stride = 0;
3104 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00003105 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003106
3107 if (num_attributes > 0)
3108 {
3109 uint32_t i;
3110 for (i=0; i<num_attributes; ++i)
3111 {
3112 attr = attributes.AttributeAtIndex(i);
3113 DWARFFormValue form_value;
3114 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3115 {
3116 switch (attr)
3117 {
3118 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3119 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3120 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3121 case DW_AT_name:
3122 type_name_cstr = form_value.AsCString(&get_debug_str_data());
3123 type_name_dbstr.SetCString(type_name_cstr);
3124 break;
3125
3126 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
3127 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3128 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3129 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003130 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003131 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
3132 case DW_AT_allocated:
3133 case DW_AT_associated:
3134 case DW_AT_data_location:
3135 case DW_AT_description:
3136 case DW_AT_ordering:
3137 case DW_AT_start_scope:
3138 case DW_AT_visibility:
3139 case DW_AT_specification:
3140 case DW_AT_abstract_origin:
3141 case DW_AT_sibling:
3142 break;
3143 }
3144 }
3145 }
3146
Greg Claytonc93237c2010-10-01 20:48:32 +00003147 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3148
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003149 Type *element_type = ResolveTypeUID(type_die_offset);
3150
3151 if (element_type)
3152 {
3153 std::vector<uint64_t> element_orders;
3154 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00003155 // We have an array that claims to have no members, lets give it at least one member...
3156 if (element_orders.empty())
3157 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003158 if (byte_stride == 0 && bit_stride == 0)
3159 byte_stride = element_type->GetByteSize();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003160 clang_type_t array_element_type = element_type->GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003161 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3162 uint64_t num_elements = 0;
3163 std::vector<uint64_t>::const_reverse_iterator pos;
3164 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3165 for (pos = element_orders.rbegin(); pos != end; ++pos)
3166 {
3167 num_elements = *pos;
3168 clang_type = type_list->GetClangASTContext().CreateArrayType (array_element_type, num_elements, num_elements * array_element_bit_stride);
3169 array_element_type = clang_type;
3170 array_element_bit_stride = array_element_bit_stride * num_elements;
3171 }
3172 ConstString empty_name;
Greg Clayton4957bf62010-09-30 21:49:03 +00003173 type_sp.reset( new Type(die->GetOffset(), this, empty_name, array_element_bit_stride / 8, NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, clang_type, false));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003174 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003175 }
3176 }
3177 }
3178 break;
3179
Greg Clayton9b81a312010-06-12 01:20:30 +00003180 case DW_TAG_ptr_to_member_type:
3181 {
3182 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3183 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3184
Greg Claytond88d7592010-09-15 08:33:30 +00003185 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00003186
3187 if (num_attributes > 0) {
3188 uint32_t i;
3189 for (i=0; i<num_attributes; ++i)
3190 {
3191 attr = attributes.AttributeAtIndex(i);
3192 DWARFFormValue form_value;
3193 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3194 {
3195 switch (attr)
3196 {
3197 case DW_AT_type:
3198 type_die_offset = form_value.Reference(dwarf_cu); break;
3199 case DW_AT_containing_type:
3200 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3201 }
3202 }
3203 }
3204
3205 Type *pointee_type = ResolveTypeUID(type_die_offset);
3206 Type *class_type = ResolveTypeUID(containing_type_die_offset);
3207
Greg Clayton1be10fc2010-09-29 01:12:09 +00003208 clang_type_t pointee_clang_type = pointee_type->GetClangType();
3209 clang_type_t class_clang_type = class_type->GetClangType();
Greg Clayton9b81a312010-06-12 01:20:30 +00003210
Greg Claytonb1320972010-07-14 00:18:15 +00003211 clang_type = type_list->GetClangASTContext().CreateMemberPointerType(pointee_clang_type, class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00003212
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003213 size_t byte_size = ClangASTType::GetClangTypeBitWidth (type_list->GetClangASTContext().getASTContext(), clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00003214
Greg Clayton4957bf62010-09-30 21:49:03 +00003215 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, NULL, clang_type, false));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003216 m_die_to_type[die] = type_sp.get();
Greg Clayton9b81a312010-06-12 01:20:30 +00003217 }
3218
3219 break;
3220 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003221 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00003222 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003223 break;
3224 }
3225
3226 if (type_sp.get())
3227 {
3228 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3229 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3230
3231 SymbolContextScope * symbol_context_scope = NULL;
3232 if (sc_parent_tag == DW_TAG_compile_unit)
3233 {
3234 symbol_context_scope = sc.comp_unit;
3235 }
3236 else if (sc.function != NULL)
3237 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003238 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003239 if (symbol_context_scope == NULL)
3240 symbol_context_scope = sc.function;
3241 }
3242
3243 if (symbol_context_scope != NULL)
3244 {
3245 type_sp->SetSymbolContextScope(symbol_context_scope);
3246 }
3247
3248// if (udt_sp.get())
3249// {
3250// if (is_forward_declaration)
3251// udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
3252// type_sp->SetUserDefinedType(udt_sp);
3253// }
3254
3255 if (type_sp.unique())
3256 {
3257 // We are ready to put this type into the uniqued list up at the module level
3258 TypeSP uniqued_type_sp(m_obj_file->GetModule()->GetTypeList()->InsertUnique(type_sp));
Greg Clayton450e3f32010-10-12 02:24:53 +00003259
3260 if (m_debug_map_symfile)
3261 m_debug_map_symfile->GetObjectFile()->GetModule()->GetTypeList()->InsertUnique (uniqued_type_sp);
3262
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003263 type_sp = uniqued_type_sp;
Greg Clayton594e5ed2010-09-27 21:07:38 +00003264 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003265 }
3266 }
3267 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00003268 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003269 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00003270 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003271 }
3272 }
3273 return type_sp;
3274}
3275
3276size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00003277SymbolFileDWARF::ParseTypes
3278(
3279 const SymbolContext& sc,
3280 DWARFCompileUnit* dwarf_cu,
3281 const DWARFDebugInfoEntry *die,
3282 bool parse_siblings,
3283 bool parse_children
3284)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003285{
3286 size_t types_added = 0;
3287 while (die != NULL)
3288 {
3289 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003290 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003291 {
3292 if (type_is_new)
3293 ++types_added;
3294 }
3295
3296 if (parse_children && die->HasChildren())
3297 {
3298 if (die->Tag() == DW_TAG_subprogram)
3299 {
3300 SymbolContext child_sc(sc);
3301 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3302 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3303 }
3304 else
3305 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3306 }
3307
3308 if (parse_siblings)
3309 die = die->GetSibling();
3310 else
3311 die = NULL;
3312 }
3313 return types_added;
3314}
3315
3316
3317size_t
3318SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3319{
3320 assert(sc.comp_unit && sc.function);
3321 size_t functions_added = 0;
3322 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3323 if (dwarf_cu)
3324 {
3325 dw_offset_t function_die_offset = sc.function->GetID();
3326 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3327 if (function_die)
3328 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003329 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003330 }
3331 }
3332
3333 return functions_added;
3334}
3335
3336
3337size_t
3338SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3339{
3340 // At least a compile unit must be valid
3341 assert(sc.comp_unit);
3342 size_t types_added = 0;
3343 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3344 if (dwarf_cu)
3345 {
3346 if (sc.function)
3347 {
3348 dw_offset_t function_die_offset = sc.function->GetID();
3349 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3350 if (func_die && func_die->HasChildren())
3351 {
3352 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3353 }
3354 }
3355 else
3356 {
3357 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3358 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3359 {
3360 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3361 }
3362 }
3363 }
3364
3365 return types_added;
3366}
3367
3368size_t
3369SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3370{
3371 if (sc.comp_unit != NULL)
3372 {
3373 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3374
3375 if (dwarf_cu == NULL)
3376 return 0;
3377
3378 if (sc.function)
3379 {
3380 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00003381
3382 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
3383 assert (func_lo_pc != DW_INVALID_ADDRESS);
3384
3385 return ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003386 }
3387 else if (sc.comp_unit)
3388 {
3389 uint32_t vars_added = 0;
3390 VariableListSP variables (sc.comp_unit->GetVariableList(false));
3391
3392 if (variables.get() == NULL)
3393 {
3394 variables.reset(new VariableList());
3395 sc.comp_unit->SetVariableList(variables);
3396
3397 // Index if we already haven't to make sure the compile units
3398 // get indexed and make their global DIE index list
3399 if (!m_indexed)
3400 Index ();
3401
Greg Claytonc685f8e2010-09-15 04:15:46 +00003402
3403 std::vector<NameToDIE::Info> global_die_info_array;
3404 const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (sc.comp_unit->GetID(), global_die_info_array);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003405 for (size_t idx=0; idx<num_globals; ++idx)
3406 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00003407 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 +00003408 if (var_sp)
3409 {
3410 variables->AddVariable(var_sp);
3411 ++vars_added;
3412 }
3413 }
3414 }
3415 return vars_added;
3416 }
3417 }
3418 return 0;
3419}
3420
3421
3422VariableSP
3423SymbolFileDWARF::ParseVariableDIE
3424(
3425 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003426 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00003427 const DWARFDebugInfoEntry *die,
3428 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003429)
3430{
3431
3432 VariableSP var_sp;
3433
3434 const dw_tag_t tag = die->Tag();
3435 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003436 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003437 if (num_attributes > 0)
3438 {
3439 const char *name = NULL;
Greg Claytona134cc12010-09-13 02:37:44 +00003440 const char *mangled = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003441 Declaration decl;
3442 uint32_t i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003443 Type *var_type = NULL;
3444 DWARFExpression location;
3445 bool is_external = false;
3446 bool is_artificial = false;
Sean Callananc7fbf732010-08-06 00:32:49 +00003447 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003448
3449 for (i=0; i<num_attributes; ++i)
3450 {
3451 dw_attr_t attr = attributes.AttributeAtIndex(i);
3452 DWARFFormValue form_value;
3453 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3454 {
3455 switch (attr)
3456 {
3457 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3458 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3459 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3460 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Claytona134cc12010-09-13 02:37:44 +00003461 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton594e5ed2010-09-27 21:07:38 +00003462 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003463 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
3464 case DW_AT_location:
3465 {
3466 if (form_value.BlockData())
3467 {
3468 const DataExtractor& debug_info_data = get_debug_info_data();
3469
3470 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3471 uint32_t block_length = form_value.Unsigned();
Greg Clayton016a95e2010-09-14 02:20:48 +00003472 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003473 }
3474 else
3475 {
3476 const DataExtractor& debug_loc_data = get_debug_loc_data();
3477 const dw_offset_t debug_loc_offset = form_value.Unsigned();
3478
3479 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
3480 if (loc_list_length > 0)
3481 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003482 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
3483 assert (func_low_pc != LLDB_INVALID_ADDRESS);
3484 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003485 }
3486 }
3487 }
3488 break;
3489
3490 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003491 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003492 case DW_AT_const_value:
3493 case DW_AT_declaration:
3494 case DW_AT_description:
3495 case DW_AT_endianity:
3496 case DW_AT_segment:
3497 case DW_AT_start_scope:
3498 case DW_AT_visibility:
3499 default:
3500 case DW_AT_abstract_origin:
3501 case DW_AT_sibling:
3502 case DW_AT_specification:
3503 break;
3504 }
3505 }
3506 }
3507
3508 if (location.IsValid())
3509 {
3510 assert(var_type != DIE_IS_BEING_PARSED);
3511
Greg Claytona134cc12010-09-13 02:37:44 +00003512 ConstString var_name;
3513 if (mangled)
3514 {
3515 Mangled mangled_var_name (mangled, true);
3516 var_name = mangled_var_name.GetDemangledName();
3517 }
3518
3519 if (!var_name && name)
3520 {
3521 var_name.SetCString(name);
3522 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003523
3524 ValueType scope = eValueTypeInvalid;
3525
3526 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3527 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3528
3529 if (tag == DW_TAG_formal_parameter)
3530 scope = eValueTypeVariableArgument;
3531 else if (is_external || parent_tag == DW_TAG_compile_unit)
3532 scope = eValueTypeVariableGlobal;
3533 else
3534 scope = eValueTypeVariableLocal;
3535
3536 SymbolContextScope * symbol_context_scope = NULL;
3537 if (parent_tag == DW_TAG_compile_unit)
3538 {
3539 symbol_context_scope = sc.comp_unit;
3540 }
3541 else if (sc.function != NULL)
3542 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003543 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003544 if (symbol_context_scope == NULL)
3545 symbol_context_scope = sc.function;
3546 }
3547
3548 assert(symbol_context_scope != NULL);
3549 var_sp.reset (new Variable(die->GetOffset(),
3550 var_name,
3551 var_type,
3552 scope,
3553 symbol_context_scope,
3554 &decl,
3555 location,
3556 is_external,
3557 is_artificial));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003558
3559 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003560 }
3561 }
3562 return var_sp;
3563}
3564
3565size_t
3566SymbolFileDWARF::ParseVariables
3567(
3568 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003569 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00003570 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003571 const DWARFDebugInfoEntry *orig_die,
3572 bool parse_siblings,
3573 bool parse_children,
3574 VariableList* cc_variable_list
3575)
3576{
3577 if (orig_die == NULL)
3578 return 0;
3579
3580 size_t vars_added = 0;
3581 const DWARFDebugInfoEntry *die = orig_die;
3582 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
3583 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3584 VariableListSP variables;
3585 switch (parent_tag)
3586 {
3587 case DW_TAG_compile_unit:
3588 if (sc.comp_unit != NULL)
3589 {
3590 variables = sc.comp_unit->GetVariableList(false);
3591 if (variables.get() == NULL)
3592 {
3593 variables.reset(new VariableList());
3594 sc.comp_unit->SetVariableList(variables);
3595 }
3596 }
3597 else
3598 {
3599 assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
3600 vars_added = 0;
3601 }
3602 break;
3603
3604 case DW_TAG_subprogram:
3605 case DW_TAG_inlined_subroutine:
3606 case DW_TAG_lexical_block:
3607 if (sc.function != NULL)
3608 {
3609 // Check to see if we already have parsed the variables for the given scope
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003610
3611 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
3612 assert (block != NULL);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003613 variables = block->GetVariableList(false, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003614 if (variables.get() == NULL)
3615 {
3616 variables.reset(new VariableList());
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003617 block->SetVariableList(variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003618 }
3619 }
3620 else
3621 {
3622 assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
3623 vars_added = 0;
3624 }
3625 break;
3626
3627 default:
3628 assert(!"Didn't find appropriate parent DIE for variable list...");
3629 break;
3630 }
3631
3632 // We need to have a variable list at this point that we can add variables to
3633 assert(variables.get());
3634
3635 while (die != NULL)
3636 {
3637 dw_tag_t tag = die->Tag();
3638
3639 // Check to see if we have already parsed this variable or constant?
Greg Clayton594e5ed2010-09-27 21:07:38 +00003640 if (m_die_to_variable_sp[die].get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003641 {
3642 // We haven't already parsed it, lets do that now.
3643 if ((tag == DW_TAG_variable) ||
3644 (tag == DW_TAG_constant) ||
3645 (tag == DW_TAG_formal_parameter && sc.function))
3646 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003647 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003648 if (var_sp)
3649 {
3650 variables->AddVariable(var_sp);
3651 ++vars_added;
3652 }
3653 }
3654 }
3655
3656 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
3657
3658 if (!skip_children && parse_children && die->HasChildren())
3659 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003660 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003661 //vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), parse_siblings, parse_children);
3662 }
3663
3664 if (parse_siblings)
3665 die = die->GetSibling();
3666 else
3667 die = NULL;
3668 }
3669
3670 if (cc_variable_list)
3671 {
3672 cc_variable_list->AddVariables(variables.get());
3673 }
3674
3675 return vars_added;
3676}
3677
3678//------------------------------------------------------------------
3679// PluginInterface protocol
3680//------------------------------------------------------------------
3681const char *
3682SymbolFileDWARF::GetPluginName()
3683{
3684 return "SymbolFileDWARF";
3685}
3686
3687const char *
3688SymbolFileDWARF::GetShortPluginName()
3689{
3690 return GetPluginNameStatic();
3691}
3692
3693uint32_t
3694SymbolFileDWARF::GetPluginVersion()
3695{
3696 return 1;
3697}
3698
3699void
3700SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
3701{
3702}
3703
3704Error
3705SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
3706{
3707 Error error;
3708 error.SetErrorString("No plug-in command are currently supported.");
3709 return error;
3710}
3711
3712Log *
3713SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
3714{
3715 return NULL;
3716}
3717