blob: 1337ba643ace627b34d20a3476d328897c5ee6c1 [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 Clayton62742b12010-11-11 01:09:45 +000056//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonc93237c2010-10-01 20:48:32 +000057
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
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000120
121ClangASTContext &
122SymbolFileDWARF::GetClangASTContext()
123{
124 return GetTypeList()->GetClangASTContext();
125}
126
127TypeList *
128SymbolFileDWARF::GetTypeList ()
129{
130 if (m_debug_map_symfile)
131 return m_debug_map_symfile->GetTypeList();
132 return m_obj_file->GetModule()->GetTypeList();
133
134}
135
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000136//----------------------------------------------------------------------
137// Gets the first parent that is a lexical block, function or inlined
138// subroutine, or compile unit.
139//----------------------------------------------------------------------
140static const DWARFDebugInfoEntry *
141GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
142{
143 const DWARFDebugInfoEntry *die;
144 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
145 {
146 dw_tag_t tag = die->Tag();
147
148 switch (tag)
149 {
150 case DW_TAG_compile_unit:
151 case DW_TAG_subprogram:
152 case DW_TAG_inlined_subroutine:
153 case DW_TAG_lexical_block:
154 return die;
155 }
156 }
157 return NULL;
158}
159
160
Greg Clayton450e3f32010-10-12 02:24:53 +0000161SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
162 SymbolFile (objfile),
163 m_debug_map_symfile (NULL),
Greg Clayton7a345282010-11-09 23:46:37 +0000164 m_clang_tu_decl (NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165 m_flags(),
166 m_data_debug_abbrev(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167 m_data_debug_frame(),
168 m_data_debug_info(),
169 m_data_debug_line(),
170 m_data_debug_loc(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171 m_data_debug_ranges(),
172 m_data_debug_str(),
173 m_abbr(),
174 m_aranges(),
175 m_info(),
176 m_line(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000177 m_function_basename_index(),
178 m_function_fullname_index(),
179 m_function_method_index(),
180 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000181 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000182 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000183 m_type_index(),
184 m_namespace_index(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000185 m_indexed(false),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000186 m_ranges()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187{
188}
189
190SymbolFileDWARF::~SymbolFileDWARF()
191{
192}
193
194bool
195SymbolFileDWARF::SupportedVersion(uint16_t version)
196{
197 return version == 2 || version == 3;
198}
199
200uint32_t
201SymbolFileDWARF::GetAbilities ()
202{
203 uint32_t abilities = 0;
204 if (m_obj_file != NULL)
205 {
206 const Section* section = NULL;
207 const SectionList *section_list = m_obj_file->GetSectionList();
208 if (section_list == NULL)
209 return 0;
210
211 uint64_t debug_abbrev_file_size = 0;
212 uint64_t debug_aranges_file_size = 0;
213 uint64_t debug_frame_file_size = 0;
214 uint64_t debug_info_file_size = 0;
215 uint64_t debug_line_file_size = 0;
216 uint64_t debug_loc_file_size = 0;
217 uint64_t debug_macinfo_file_size = 0;
218 uint64_t debug_pubnames_file_size = 0;
219 uint64_t debug_pubtypes_file_size = 0;
220 uint64_t debug_ranges_file_size = 0;
221 uint64_t debug_str_file_size = 0;
222
223 static ConstString g_dwarf_section_name ("__DWARF");
224
225 section = section_list->FindSectionByName(g_dwarf_section_name).get();
226
227 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000228 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000229 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
Greg Clayton4ceb9982010-07-21 22:54:26 +0000230 section_list = &section->GetChildren ();
231 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232
Greg Clayton4ceb9982010-07-21 22:54:26 +0000233 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000234 if (section != NULL)
235 {
236 debug_info_file_size = section->GetByteSize();
237
Greg Clayton4ceb9982010-07-21 22:54:26 +0000238 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000239 if (section)
240 debug_abbrev_file_size = section->GetByteSize();
241 else
242 m_flags.Set (flagsGotDebugAbbrevData);
243
Greg Clayton4ceb9982010-07-21 22:54:26 +0000244 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245 if (section)
246 debug_aranges_file_size = section->GetByteSize();
247 else
248 m_flags.Set (flagsGotDebugArangesData);
249
Greg Clayton4ceb9982010-07-21 22:54:26 +0000250 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000251 if (section)
252 debug_frame_file_size = section->GetByteSize();
253 else
254 m_flags.Set (flagsGotDebugFrameData);
255
Greg Clayton4ceb9982010-07-21 22:54:26 +0000256 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000257 if (section)
258 debug_line_file_size = section->GetByteSize();
259 else
260 m_flags.Set (flagsGotDebugLineData);
261
Greg Clayton4ceb9982010-07-21 22:54:26 +0000262 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263 if (section)
264 debug_loc_file_size = section->GetByteSize();
265 else
266 m_flags.Set (flagsGotDebugLocData);
267
Greg Clayton4ceb9982010-07-21 22:54:26 +0000268 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269 if (section)
270 debug_macinfo_file_size = section->GetByteSize();
271 else
272 m_flags.Set (flagsGotDebugMacInfoData);
273
Greg Clayton4ceb9982010-07-21 22:54:26 +0000274 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000275 if (section)
276 debug_pubnames_file_size = section->GetByteSize();
277 else
278 m_flags.Set (flagsGotDebugPubNamesData);
279
Greg Clayton4ceb9982010-07-21 22:54:26 +0000280 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000281 if (section)
282 debug_pubtypes_file_size = section->GetByteSize();
283 else
284 m_flags.Set (flagsGotDebugPubTypesData);
285
Greg Clayton4ceb9982010-07-21 22:54:26 +0000286 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000287 if (section)
288 debug_ranges_file_size = section->GetByteSize();
289 else
290 m_flags.Set (flagsGotDebugRangesData);
291
Greg Clayton4ceb9982010-07-21 22:54:26 +0000292 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000293 if (section)
294 debug_str_file_size = section->GetByteSize();
295 else
296 m_flags.Set (flagsGotDebugStrData);
297 }
298
299 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
300 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
301
302 if (debug_line_file_size > 0)
303 abilities |= LineTables;
304
305 if (debug_aranges_file_size > 0)
306 abilities |= AddressAcceleratorTable;
307
308 if (debug_pubnames_file_size > 0)
309 abilities |= FunctionAcceleratorTable;
310
311 if (debug_pubtypes_file_size > 0)
312 abilities |= TypeAcceleratorTable;
313
314 if (debug_macinfo_file_size > 0)
315 abilities |= MacroInformation;
316
317 if (debug_frame_file_size > 0)
318 abilities |= CallFrameInformation;
319 }
320 return abilities;
321}
322
323const DataExtractor&
Greg Clayton4ceb9982010-07-21 22:54:26 +0000324SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325{
326 if (m_flags.IsClear (got_flag))
327 {
328 m_flags.Set (got_flag);
329 const SectionList *section_list = m_obj_file->GetSectionList();
330 if (section_list)
331 {
Greg Clayton4ceb9982010-07-21 22:54:26 +0000332 Section *section = section_list->FindSectionByType(sect_type, true).get();
333 if (section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000334 {
335 // See if we memory mapped the DWARF segment?
336 if (m_dwarf_data.GetByteSize())
337 {
338 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
339 }
340 else
341 {
342 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
343 data.Clear();
344 }
345 }
346 }
347 }
348 return data;
349}
350
351const DataExtractor&
352SymbolFileDWARF::get_debug_abbrev_data()
353{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000354 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000355}
356
357const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358SymbolFileDWARF::get_debug_frame_data()
359{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000360 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361}
362
363const DataExtractor&
364SymbolFileDWARF::get_debug_info_data()
365{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000366 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000367}
368
369const DataExtractor&
370SymbolFileDWARF::get_debug_line_data()
371{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000372 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373}
374
375const DataExtractor&
376SymbolFileDWARF::get_debug_loc_data()
377{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000378 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000379}
380
381const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000382SymbolFileDWARF::get_debug_ranges_data()
383{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000384 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385}
386
387const DataExtractor&
388SymbolFileDWARF::get_debug_str_data()
389{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000390 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000391}
392
393
394DWARFDebugAbbrev*
395SymbolFileDWARF::DebugAbbrev()
396{
397 if (m_abbr.get() == NULL)
398 {
399 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
400 if (debug_abbrev_data.GetByteSize() > 0)
401 {
402 m_abbr.reset(new DWARFDebugAbbrev());
403 if (m_abbr.get())
404 m_abbr->Parse(debug_abbrev_data);
405 }
406 }
407 return m_abbr.get();
408}
409
410const DWARFDebugAbbrev*
411SymbolFileDWARF::DebugAbbrev() const
412{
413 return m_abbr.get();
414}
415
416DWARFDebugAranges*
417SymbolFileDWARF::DebugAranges()
418{
Greg Clayton016a95e2010-09-14 02:20:48 +0000419 // It turns out that llvm-gcc doesn't generate .debug_aranges in .o files
420 // and we are already parsing all of the DWARF because the .debug_pubnames
421 // is useless (it only mentions symbols that are externally visible), so
422 // don't use the .debug_aranges section, we should be using a debug aranges
423 // we got from SymbolFileDWARF::Index().
424
425 if (!m_indexed)
426 Index();
427
428
429// if (m_aranges.get() == NULL)
430// {
431// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
432// m_aranges.reset(new DWARFDebugAranges());
433// if (m_aranges.get())
434// {
435// const DataExtractor &debug_aranges_data = get_debug_aranges_data();
436// if (debug_aranges_data.GetByteSize() > 0)
437// m_aranges->Extract(debug_aranges_data);
438// else
439// m_aranges->Generate(this);
440// }
441// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000442 return m_aranges.get();
443}
444
445const DWARFDebugAranges*
446SymbolFileDWARF::DebugAranges() const
447{
448 return m_aranges.get();
449}
450
451
452DWARFDebugInfo*
453SymbolFileDWARF::DebugInfo()
454{
455 if (m_info.get() == NULL)
456 {
457 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
458 if (get_debug_info_data().GetByteSize() > 0)
459 {
460 m_info.reset(new DWARFDebugInfo());
461 if (m_info.get())
462 {
463 m_info->SetDwarfData(this);
464 }
465 }
466 }
467 return m_info.get();
468}
469
470const DWARFDebugInfo*
471SymbolFileDWARF::DebugInfo() const
472{
473 return m_info.get();
474}
475
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000476DWARFCompileUnit*
477SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
478{
479 DWARFDebugInfo* info = DebugInfo();
480 if (info)
481 return info->GetCompileUnit(cu_uid).get();
482 return NULL;
483}
484
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000485
486DWARFDebugRanges*
487SymbolFileDWARF::DebugRanges()
488{
489 if (m_ranges.get() == NULL)
490 {
491 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
492 if (get_debug_ranges_data().GetByteSize() > 0)
493 {
494 m_ranges.reset(new DWARFDebugRanges());
495 if (m_ranges.get())
496 m_ranges->Extract(this);
497 }
498 }
499 return m_ranges.get();
500}
501
502const DWARFDebugRanges*
503SymbolFileDWARF::DebugRanges() const
504{
505 return m_ranges.get();
506}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000507
508bool
Greg Clayton96d7d742010-11-10 23:42:09 +0000509SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000510{
Greg Clayton96d7d742010-11-10 23:42:09 +0000511 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000512 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000513 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000514 if (cu_die)
515 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000516 const char * cu_die_name = cu_die->GetName(this, curr_cu);
517 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
518 LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000519 if (cu_die_name)
520 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000521 FileSpec cu_file_spec;
522
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523 if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0])
524 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000525 // If we have a full path to the compile unit, we don't need to resolve
526 // the file. This can be expensive e.g. when the source files are NFS mounted.
527 cu_file_spec.SetFile (cu_die_name, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000528 }
529 else
530 {
531 std::string fullpath(cu_comp_dir);
532 if (*fullpath.rbegin() != '/')
533 fullpath += '/';
534 fullpath += cu_die_name;
Jim Ingham0909e5f2010-09-16 00:57:33 +0000535 cu_file_spec.SetFile (fullpath.c_str(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000536 }
537
Greg Clayton96d7d742010-11-10 23:42:09 +0000538 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), curr_cu, cu_file_spec, curr_cu->GetOffset(), class_language));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000539 if (compile_unit_sp.get())
540 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000541 curr_cu->SetUserData(compile_unit_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000542 return true;
543 }
544 }
545 }
546 }
547 return false;
548}
549
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000550uint32_t
551SymbolFileDWARF::GetNumCompileUnits()
552{
553 DWARFDebugInfo* info = DebugInfo();
554 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000555 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000556 return 0;
557}
558
559CompUnitSP
560SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
561{
562 CompUnitSP comp_unit;
563 DWARFDebugInfo* info = DebugInfo();
564 if (info)
565 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000566 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
567 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000568 {
569 // Our symbol vendor shouldn't be asking us to add a compile unit that
570 // has already been added to it, which this DWARF plug-in knows as it
571 // stores the lldb compile unit (CompileUnit) pointer in each
572 // DWARFCompileUnit object when it gets added.
Greg Clayton96d7d742010-11-10 23:42:09 +0000573 assert(curr_cu->GetUserData() == NULL);
574 ParseCompileUnit(curr_cu, comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000575 }
576 }
577 return comp_unit;
578}
579
580static void
581AddRangesToBlock
582(
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000583 Block& block,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000584 DWARFDebugRanges::RangeList& ranges,
585 addr_t block_base_addr
586)
587{
588 ranges.SubtractOffset (block_base_addr);
589 size_t range_idx = 0;
590 const DWARFDebugRanges::Range *debug_range;
591 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
592 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000593 block.AddRange(debug_range->begin_offset, debug_range->end_offset);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000594 }
595}
596
597
598Function *
Greg Clayton0fffff52010-09-24 05:15:53 +0000599SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000600{
601 DWARFDebugRanges::RangeList func_ranges;
602 const char *name = NULL;
603 const char *mangled = NULL;
604 int decl_file = 0;
605 int decl_line = 0;
606 int decl_column = 0;
607 int call_file = 0;
608 int call_line = 0;
609 int call_column = 0;
610 DWARFExpression frame_base;
611
Greg Claytonc93237c2010-10-01 20:48:32 +0000612 assert (die->Tag() == DW_TAG_subprogram);
613
614 if (die->Tag() != DW_TAG_subprogram)
615 return NULL;
616
617 const DWARFDebugInfoEntry *parent_die = die->GetParent();
618 switch (parent_die->Tag())
619 {
620 case DW_TAG_structure_type:
621 case DW_TAG_class_type:
622 // We have methods of a class or struct
623 {
624 Type *class_type = ResolveType (dwarf_cu, parent_die);
625 if (class_type)
626 class_type->GetClangType();
627 }
628 break;
629
630 default:
631 // Parse the function prototype as a type that can then be added to concrete function instance
632 ParseTypes (sc, dwarf_cu, die, false, false);
633 break;
634 }
635
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000636 //FixupTypes();
637
638 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
639 {
640 // Union of all ranges in the function DIE (if the function is discontiguous)
641 AddressRange func_range;
642 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
643 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
644 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
645 {
646 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
647 if (func_range.GetBaseAddress().IsValid())
648 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
649 }
650
651 if (func_range.GetBaseAddress().IsValid())
652 {
653 Mangled func_name;
654 if (mangled)
655 func_name.SetValue(mangled, true);
656 else if (name)
657 func_name.SetValue(name, false);
658
659 FunctionSP func_sp;
660 std::auto_ptr<Declaration> decl_ap;
661 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Greg Claytond7e05462010-11-14 00:22:48 +0000662 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
663 decl_line,
664 decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000665
Greg Clayton594e5ed2010-09-27 21:07:38 +0000666 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000667
668 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
669
670 func_range.GetBaseAddress().ResolveLinkedAddress();
671
672 func_sp.reset(new Function (sc.comp_unit,
673 die->GetOffset(), // UserID is the DIE offset
674 die->GetOffset(),
675 func_name,
676 func_type,
677 func_range)); // first address range
678
679 if (func_sp.get() != NULL)
680 {
681 func_sp->GetFrameBaseExpression() = frame_base;
682 sc.comp_unit->AddFunction(func_sp);
683 return func_sp.get();
684 }
685 }
686 }
687 return NULL;
688}
689
690size_t
691SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
692{
693 assert (sc.comp_unit);
694 size_t functions_added = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +0000695 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000696 if (dwarf_cu)
697 {
698 DWARFDIECollection function_dies;
699 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
700 size_t func_idx;
701 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
702 {
703 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
704 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
705 {
706 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
707 ++functions_added;
708 }
709 }
710 //FixupTypes();
711 }
712 return functions_added;
713}
714
715bool
716SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
717{
718 assert (sc.comp_unit);
Greg Clayton96d7d742010-11-10 23:42:09 +0000719 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
720 assert (curr_cu);
721 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000722
723 if (cu_die)
724 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000725 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
726 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000727
728 // All file indexes in DWARF are one based and a file of index zero is
729 // supposed to be the compile unit itself.
730 support_files.Append (*sc.comp_unit);
731
732 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
733 }
734 return false;
735}
736
737struct ParseDWARFLineTableCallbackInfo
738{
739 LineTable* line_table;
740 const SectionList *section_list;
741 lldb::addr_t prev_sect_file_base_addr;
742 lldb::addr_t curr_sect_file_base_addr;
743 bool is_oso_for_debug_map;
744 bool prev_in_final_executable;
745 DWARFDebugLine::Row prev_row;
746 SectionSP prev_section_sp;
747 SectionSP curr_section_sp;
748};
749
750//----------------------------------------------------------------------
751// ParseStatementTableCallback
752//----------------------------------------------------------------------
753static void
754ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
755{
756 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
757 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
758 {
759 // Just started parsing the line table
760 }
761 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
762 {
763 // Done parsing line table, nothing to do for the cleanup
764 }
765 else
766 {
767 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
768 // We have a new row, lets append it
769
770 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
771 {
772 info->prev_section_sp = info->curr_section_sp;
773 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
774 // If this is an end sequence entry, then we subtract one from the
775 // address to make sure we get an address that is not the end of
776 // a section.
777 if (state.end_sequence && state.address != 0)
778 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
779 else
780 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
781
782 if (info->curr_section_sp.get())
783 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
784 else
785 info->curr_sect_file_base_addr = 0;
786 }
787 if (info->curr_section_sp.get())
788 {
789 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
790 // Check for the fancy section magic to determine if we
791
792 if (info->is_oso_for_debug_map)
793 {
794 // When this is a debug map object file that contains DWARF
795 // (referenced from an N_OSO debug map nlist entry) we will have
796 // a file address in the file range for our section from the
797 // original .o file, and a load address in the executable that
798 // contains the debug map.
799 //
800 // If the sections for the file range and load range are
801 // different, we have a remapped section for the function and
802 // this address is resolved. If they are the same, then the
803 // function for this address didn't make it into the final
804 // executable.
805 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
806
807 // If we are doing DWARF with debug map, then we need to carefully
808 // add each line table entry as there may be gaps as functions
809 // get moved around or removed.
810 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
811 {
812 if (info->prev_in_final_executable)
813 {
814 bool terminate_previous_entry = false;
815 if (!curr_in_final_executable)
816 {
817 // Check for the case where the previous line entry
818 // in a function made it into the final executable,
819 // yet the current line entry falls in a function
820 // that didn't. The line table used to be contiguous
821 // through this address range but now it isn't. We
822 // need to terminate the previous line entry so
823 // that we can reconstruct the line range correctly
824 // for it and to keep the line table correct.
825 terminate_previous_entry = true;
826 }
827 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
828 {
829 // Check for cases where the line entries used to be
830 // contiguous address ranges, but now they aren't.
831 // This can happen when order files specify the
832 // ordering of the functions.
833 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
834 Section *curr_sect = info->curr_section_sp.get();
835 Section *prev_sect = info->prev_section_sp.get();
836 assert (curr_sect->GetLinkedSection());
837 assert (prev_sect->GetLinkedSection());
838 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
839 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
840 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
841 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
842 if (object_file_addr_delta != linked_file_addr_delta)
843 terminate_previous_entry = true;
844 }
845
846 if (terminate_previous_entry)
847 {
848 line_table->InsertLineEntry (info->prev_section_sp,
849 state.address - info->prev_sect_file_base_addr,
850 info->prev_row.line,
851 info->prev_row.column,
852 info->prev_row.file,
853 false, // is_stmt
854 false, // basic_block
855 false, // state.prologue_end
856 false, // state.epilogue_begin
857 true); // end_sequence);
858 }
859 }
860 }
861
862 if (curr_in_final_executable)
863 {
864 line_table->InsertLineEntry (info->curr_section_sp,
865 curr_line_section_offset,
866 state.line,
867 state.column,
868 state.file,
869 state.is_stmt,
870 state.basic_block,
871 state.prologue_end,
872 state.epilogue_begin,
873 state.end_sequence);
874 info->prev_section_sp = info->curr_section_sp;
875 }
876 else
877 {
878 // If the current address didn't make it into the final
879 // executable, the current section will be the __text
880 // segment in the .o file, so we need to clear this so
881 // we can catch the next function that did make it into
882 // the final executable.
883 info->prev_section_sp.reset();
884 info->curr_section_sp.reset();
885 }
886
887 info->prev_in_final_executable = curr_in_final_executable;
888 }
889 else
890 {
891 // We are not in an object file that contains DWARF for an
892 // N_OSO, this is just a normal DWARF file. The DWARF spec
893 // guarantees that the addresses will be in increasing order
894 // so, since we store line tables in file address order, we
895 // can always just append the line entry without needing to
896 // search for the correct insertion point (we don't need to
897 // use LineEntry::InsertLineEntry()).
898 line_table->AppendLineEntry (info->curr_section_sp,
899 curr_line_section_offset,
900 state.line,
901 state.column,
902 state.file,
903 state.is_stmt,
904 state.basic_block,
905 state.prologue_end,
906 state.epilogue_begin,
907 state.end_sequence);
908 }
909 }
910
911 info->prev_row = state;
912 }
913}
914
915bool
916SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
917{
918 assert (sc.comp_unit);
919 if (sc.comp_unit->GetLineTable() != NULL)
920 return true;
921
922 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
923 if (dwarf_cu)
924 {
925 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
926 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
927 if (cu_line_offset != DW_INVALID_OFFSET)
928 {
929 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
930 if (line_table_ap.get())
931 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000932 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 +0000933 uint32_t offset = cu_line_offset;
934 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
935 sc.comp_unit->SetLineTable(line_table_ap.release());
936 return true;
937 }
938 }
939 }
940 return false;
941}
942
943size_t
944SymbolFileDWARF::ParseFunctionBlocks
945(
946 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000947 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +0000948 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000949 const DWARFDebugInfoEntry *die,
950 addr_t subprogram_low_pc,
951 bool parse_siblings,
952 bool parse_children
953)
954{
955 size_t blocks_added = 0;
956 while (die != NULL)
957 {
958 dw_tag_t tag = die->Tag();
959
960 switch (tag)
961 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000962 case DW_TAG_inlined_subroutine:
Jim Inghamb0be4422010-08-12 01:20:14 +0000963 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000964 case DW_TAG_lexical_block:
965 {
966 DWARFDebugRanges::RangeList ranges;
967 const char *name = NULL;
968 const char *mangled_name = NULL;
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000969 Block *block = NULL;
970 if (tag != DW_TAG_subprogram)
971 {
972 BlockSP block_sp(new Block (die->GetOffset()));
973 parent_block->AddChild(block_sp);
974 block = block_sp.get();
975 }
976 else
977 {
978 block = parent_block;
979 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000980
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000981 int decl_file = 0;
982 int decl_line = 0;
983 int decl_column = 0;
984 int call_file = 0;
985 int call_line = 0;
986 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000987 if (die->GetDIENamesAndRanges (this,
988 dwarf_cu,
989 name,
990 mangled_name,
991 ranges,
992 decl_file, decl_line, decl_column,
993 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000994 {
995 if (tag == DW_TAG_subprogram)
996 {
997 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
998 subprogram_low_pc = ranges.LowestAddress(0);
999 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001000 else if (tag == DW_TAG_inlined_subroutine)
1001 {
1002 // We get called here for inlined subroutines in two ways.
1003 // The first time is when we are making the Function object
1004 // for this inlined concrete instance. Since we're creating a top level block at
1005 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1006 // adjust the containing address.
1007 // The second time is when we are parsing the blocks inside the function that contains
1008 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1009 // function the offset will be for that function.
1010 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1011 {
1012 subprogram_low_pc = ranges.LowestAddress(0);
1013 }
1014 }
1015
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001016 AddRangesToBlock (*block, ranges, subprogram_low_pc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001017
1018 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1019 {
1020 std::auto_ptr<Declaration> decl_ap;
1021 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001022 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1023 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001024
1025 std::auto_ptr<Declaration> call_ap;
1026 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001027 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1028 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001029
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001030 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001031 }
1032
1033 ++blocks_added;
1034
1035 if (parse_children && die->HasChildren())
1036 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001037 blocks_added += ParseFunctionBlocks (sc,
1038 block,
1039 dwarf_cu,
1040 die->GetFirstChild(),
1041 subprogram_low_pc,
1042 true,
1043 true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001044 }
1045 }
1046 }
1047 break;
1048 default:
1049 break;
1050 }
1051
1052 if (parse_siblings)
1053 die = die->GetSibling();
1054 else
1055 die = NULL;
1056 }
1057 return blocks_added;
1058}
1059
1060size_t
1061SymbolFileDWARF::ParseChildMembers
1062(
1063 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001064 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001065 const DWARFDebugInfoEntry *parent_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001066 clang_type_t class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001067 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001068 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1069 std::vector<int>& member_accessibilities,
Greg Claytonc93237c2010-10-01 20:48:32 +00001070 DWARFDIECollection& member_function_dies,
Sean Callananc7fbf732010-08-06 00:32:49 +00001071 AccessType& default_accessibility,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001072 bool &is_a_class
1073)
1074{
1075 if (parent_die == NULL)
1076 return 0;
1077
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001078 size_t count = 0;
1079 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00001080 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
1081
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001082 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1083 {
1084 dw_tag_t tag = die->Tag();
1085
1086 switch (tag)
1087 {
1088 case DW_TAG_member:
1089 {
1090 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001091 const size_t num_attributes = die->GetAttributes (this,
1092 dwarf_cu,
1093 fixed_form_sizes,
1094 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001095 if (num_attributes > 0)
1096 {
1097 Declaration decl;
Greg Clayton73b472d2010-10-27 03:32:59 +00001098 //DWARFExpression location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001099 const char *name = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00001100 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001101 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001102 AccessType accessibility = eAccessNone;
Greg Clayton73b472d2010-10-27 03:32:59 +00001103 //off_t member_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001104 size_t byte_size = 0;
1105 size_t bit_offset = 0;
1106 size_t bit_size = 0;
1107 uint32_t i;
Greg Clayton24739922010-10-13 03:15:28 +00001108 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001109 {
1110 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1111 DWARFFormValue form_value;
1112 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1113 {
1114 switch (attr)
1115 {
1116 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1117 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1118 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1119 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1120 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1121 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1122 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1123 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1124 case DW_AT_data_member_location:
Greg Clayton73b472d2010-10-27 03:32:59 +00001125// if (form_value.BlockData())
1126// {
1127// Value initialValue(0);
1128// Value memberOffset(0);
1129// const DataExtractor& debug_info_data = get_debug_info_data();
1130// uint32_t block_length = form_value.Unsigned();
1131// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1132// if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1133// {
1134// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1135// }
1136// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001137 break;
1138
Greg Clayton8cf05932010-07-22 18:30:50 +00001139 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Clayton24739922010-10-13 03:15:28 +00001140 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001141 case DW_AT_declaration:
1142 case DW_AT_description:
1143 case DW_AT_mutable:
1144 case DW_AT_visibility:
1145 default:
1146 case DW_AT_sibling:
1147 break;
1148 }
1149 }
1150 }
Sean Callanan5a477cf2010-10-30 01:56:10 +00001151
1152 // FIXME: Make Clang ignore Objective-C accessibility for expressions
1153
1154 if (class_language == eLanguageTypeObjC ||
1155 class_language == eLanguageTypeObjC_plus_plus)
1156 accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001157
Greg Clayton24739922010-10-13 03:15:28 +00001158 if (is_artificial == false)
1159 {
1160 Type *member_type = ResolveTypeUID(encoding_uid);
1161 assert(member_type);
1162 if (accessibility == eAccessNone)
1163 accessibility = default_accessibility;
1164 member_accessibilities.push_back(accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001165
Greg Claytonba2d22d2010-11-13 22:57:37 +00001166 GetClangASTContext().AddFieldToRecordType (class_clang_type,
1167 name,
1168 member_type->GetClangLayoutType(),
1169 accessibility,
1170 bit_size);
Greg Clayton24739922010-10-13 03:15:28 +00001171 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001172 }
1173 }
1174 break;
1175
1176 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00001177 // Let the type parsing code handle this one for us.
1178 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001179 break;
1180
1181 case DW_TAG_inheritance:
1182 {
1183 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00001184 if (default_accessibility == eAccessNone)
1185 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001186 // TODO: implement DW_TAG_inheritance type parsing
1187 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001188 const size_t num_attributes = die->GetAttributes (this,
1189 dwarf_cu,
1190 fixed_form_sizes,
1191 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001192 if (num_attributes > 0)
1193 {
1194 Declaration decl;
1195 DWARFExpression location;
1196 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001197 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001198 bool is_virtual = false;
1199 bool is_base_of_class = true;
1200 off_t member_offset = 0;
1201 uint32_t i;
1202 for (i=0; i<num_attributes; ++i)
1203 {
1204 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1205 DWARFFormValue form_value;
1206 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1207 {
1208 switch (attr)
1209 {
1210 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1211 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1212 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1213 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1214 case DW_AT_data_member_location:
1215 if (form_value.BlockData())
1216 {
1217 Value initialValue(0);
1218 Value memberOffset(0);
1219 const DataExtractor& debug_info_data = get_debug_info_data();
1220 uint32_t block_length = form_value.Unsigned();
1221 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
Greg Claytonba2d22d2010-11-13 22:57:37 +00001222 if (DWARFExpression::Evaluate (NULL,
1223 NULL,
1224 debug_info_data,
1225 NULL,
1226 NULL,
1227 block_offset,
1228 block_length,
1229 eRegisterKindDWARF,
1230 &initialValue,
1231 memberOffset,
1232 NULL))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001233 {
1234 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1235 }
1236 }
1237 break;
1238
1239 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00001240 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001241 break;
1242
1243 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1244 default:
1245 case DW_AT_sibling:
1246 break;
1247 }
1248 }
1249 }
1250
Greg Clayton526e5af2010-11-13 03:52:47 +00001251 Type *base_class_type = ResolveTypeUID(encoding_uid);
1252 assert(base_class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001253
1254 if (class_language == eLanguageTypeObjC)
1255 {
Greg Clayton526e5af2010-11-13 03:52:47 +00001256 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_type->GetClangType());
Greg Clayton9e409562010-07-28 02:04:09 +00001257 }
1258 else
1259 {
Greg Claytonba2d22d2010-11-13 22:57:37 +00001260 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_type->GetClangType(),
1261 accessibility,
1262 is_virtual,
1263 is_base_of_class));
Greg Clayton9e409562010-07-28 02:04:09 +00001264 assert(base_classes.back());
1265 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001266 }
1267 }
1268 break;
1269
1270 default:
1271 break;
1272 }
1273 }
1274 return count;
1275}
1276
1277
1278clang::DeclContext*
1279SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1280{
1281 DWARFDebugInfo* debug_info = DebugInfo();
1282 if (debug_info)
1283 {
1284 DWARFCompileUnitSP cu_sp;
1285 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1286 if (die)
1287 return GetClangDeclContextForDIE (cu_sp.get(), die);
1288 }
1289 return NULL;
1290}
1291
1292Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001293SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001294{
1295 DWARFDebugInfo* debug_info = DebugInfo();
1296 if (debug_info)
1297 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001298 DWARFCompileUnitSP cu_sp;
1299 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001300 if (type_die != NULL)
Greg Clayton594e5ed2010-09-27 21:07:38 +00001301 return ResolveType (cu_sp.get(), type_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001302 }
1303 return NULL;
1304}
1305
Greg Clayton1be10fc2010-09-29 01:12:09 +00001306lldb::clang_type_t
1307SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1308{
1309 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Claytonc93237c2010-10-01 20:48:32 +00001310 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (ClangASTType::RemoveFastQualifiers(clang_type));
Greg Clayton1be10fc2010-09-29 01:12:09 +00001311 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001312 {
1313 // We have already resolved this type...
1314 return clang_type;
1315 }
1316 // Once we start resolving this type, remove it from the forward declaration
1317 // map in case anyone child members or other types require this type to get resolved.
1318 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1319 // are done.
1320 m_forward_decl_clang_type_to_die.erase (ClangASTType::RemoveFastQualifiers(clang_type));
1321
Greg Clayton1be10fc2010-09-29 01:12:09 +00001322
Greg Clayton450e3f32010-10-12 02:24:53 +00001323 DWARFDebugInfo* debug_info = DebugInfo();
1324
Greg Clayton96d7d742010-11-10 23:42:09 +00001325 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001326 Type *type = m_die_to_type.lookup (die);
1327
1328 const dw_tag_t tag = die->Tag();
1329
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001330 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n",
1331 die->GetOffset(),
1332 DW_TAG_value_to_name(tag),
1333 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001334 assert (clang_type);
1335 DWARFDebugInfoEntry::Attributes attributes;
1336
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001337 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001338
1339 switch (tag)
1340 {
1341 case DW_TAG_structure_type:
1342 case DW_TAG_union_type:
1343 case DW_TAG_class_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001344 ast.StartTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001345 if (die->HasChildren())
1346 {
1347 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton450e3f32010-10-12 02:24:53 +00001348 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1349 if (is_objc_class)
Greg Claytonc93237c2010-10-01 20:48:32 +00001350 class_language = eLanguageTypeObjC;
1351
1352 int tag_decl_kind = -1;
1353 AccessType default_accessibility = eAccessNone;
1354 if (tag == DW_TAG_structure_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001355 {
Greg Claytonc93237c2010-10-01 20:48:32 +00001356 tag_decl_kind = clang::TTK_Struct;
1357 default_accessibility = eAccessPublic;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001358 }
Greg Claytonc93237c2010-10-01 20:48:32 +00001359 else if (tag == DW_TAG_union_type)
1360 {
1361 tag_decl_kind = clang::TTK_Union;
1362 default_accessibility = eAccessPublic;
1363 }
1364 else if (tag == DW_TAG_class_type)
1365 {
1366 tag_decl_kind = clang::TTK_Class;
1367 default_accessibility = eAccessPrivate;
1368 }
1369
Greg Clayton96d7d742010-11-10 23:42:09 +00001370 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
Greg Claytonc93237c2010-10-01 20:48:32 +00001371 std::vector<clang::CXXBaseSpecifier *> base_classes;
1372 std::vector<int> member_accessibilities;
1373 bool is_a_class = false;
1374 // Parse members and base classes first
1375 DWARFDIECollection member_function_dies;
1376
1377 ParseChildMembers (sc,
Greg Clayton96d7d742010-11-10 23:42:09 +00001378 curr_cu,
Greg Claytonc93237c2010-10-01 20:48:32 +00001379 die,
1380 clang_type,
1381 class_language,
1382 base_classes,
1383 member_accessibilities,
1384 member_function_dies,
1385 default_accessibility,
1386 is_a_class);
1387
1388 // Now parse any methods if there were any...
1389 size_t num_functions = member_function_dies.Size();
1390 if (num_functions > 0)
1391 {
1392 for (size_t i=0; i<num_functions; ++i)
1393 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001394 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
Greg Claytonc93237c2010-10-01 20:48:32 +00001395 }
1396 }
1397
Greg Clayton450e3f32010-10-12 02:24:53 +00001398 if (class_language == eLanguageTypeObjC)
1399 {
1400 std::string class_str (ClangASTContext::GetTypeName (clang_type));
1401 if (!class_str.empty())
1402 {
1403
1404 ConstString class_name (class_str.c_str());
1405 std::vector<NameToDIE::Info> method_die_infos;
1406 if (m_objc_class_selectors_index.Find (class_name, method_die_infos))
1407 {
1408 DWARFCompileUnit* method_cu = NULL;
1409 DWARFCompileUnit* prev_method_cu = NULL;
1410 const size_t num_objc_methods = method_die_infos.size();
1411 for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu)
1412 {
1413 method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx);
1414
1415 if (method_cu != prev_method_cu)
1416 method_cu->ExtractDIEsIfNeeded (false);
1417
1418 DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx);
1419
1420 ResolveType (method_cu, method_die);
1421 }
1422 }
1423 }
1424 }
1425
Greg Claytonc93237c2010-10-01 20:48:32 +00001426 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1427 // need to tell the clang type it is actually a class.
1428 if (class_language != eLanguageTypeObjC)
1429 {
1430 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001431 ast.SetTagTypeKind (clang_type, clang::TTK_Class);
Greg Claytonc93237c2010-10-01 20:48:32 +00001432 }
1433
1434 // Since DW_TAG_structure_type gets used for both classes
1435 // and structures, we may need to set any DW_TAG_member
1436 // fields to have a "private" access if none was specified.
1437 // When we parsed the child members we tracked that actual
1438 // accessibility value for each DW_TAG_member in the
1439 // "member_accessibilities" array. If the value for the
1440 // member is zero, then it was set to the "default_accessibility"
1441 // which for structs was "public". Below we correct this
1442 // by setting any fields to "private" that weren't correctly
1443 // set.
1444 if (is_a_class && !member_accessibilities.empty())
1445 {
1446 // This is a class and all members that didn't have
1447 // their access specified are private.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001448 ast.SetDefaultAccessForRecordFields (clang_type,
1449 eAccessPrivate,
1450 &member_accessibilities.front(),
1451 member_accessibilities.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001452 }
1453
1454 if (!base_classes.empty())
1455 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001456 ast.SetBaseClassesForClassType (clang_type,
1457 &base_classes.front(),
1458 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001459
1460 // Clang will copy each CXXBaseSpecifier in "base_classes"
1461 // so we have to free them all.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001462 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1463 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001464 }
1465
1466 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001467 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001468 return clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001469
1470 case DW_TAG_enumeration_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001471 ast.StartTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001472 if (die->HasChildren())
1473 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001474 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1475 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001476 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001477 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001478 return clang_type;
1479
1480 default:
1481 assert(false && "not a forward clang type decl!");
1482 break;
1483 }
1484 return NULL;
1485}
1486
Greg Claytonc685f8e2010-09-15 04:15:46 +00001487Type*
Greg Clayton96d7d742010-11-10 23:42:09 +00001488SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001489{
1490 if (type_die != NULL)
1491 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00001492 Type *type = m_die_to_type.lookup (type_die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001493 if (type == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001494 type = GetTypeForDIE (curr_cu, type_die).get();
Greg Clayton24739922010-10-13 03:15:28 +00001495 if (assert_not_being_parsed)
1496 assert (type != DIE_IS_BEING_PARSED);
Greg Clayton594e5ed2010-09-27 21:07:38 +00001497 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001498 }
1499 return NULL;
1500}
1501
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001502CompileUnit*
Greg Clayton96d7d742010-11-10 23:42:09 +00001503SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001504{
1505 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton96d7d742010-11-10 23:42:09 +00001506 if (curr_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001507 {
1508 // The symbol vendor doesn't know about this compile unit, we
1509 // need to parse and add it to the symbol vendor object.
1510 CompUnitSP dc_cu;
Greg Clayton96d7d742010-11-10 23:42:09 +00001511 ParseCompileUnit(curr_cu, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001512 if (dc_cu.get())
1513 {
1514 // Figure out the compile unit index if we weren't given one
Greg Clayton016a95e2010-09-14 02:20:48 +00001515 if (cu_idx == UINT32_MAX)
Greg Clayton96d7d742010-11-10 23:42:09 +00001516 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001517
1518 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
Greg Clayton450e3f32010-10-12 02:24:53 +00001519
1520 if (m_debug_map_symfile)
1521 m_debug_map_symfile->SetCompileUnit(this, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001522 }
1523 }
Greg Clayton96d7d742010-11-10 23:42:09 +00001524 return (CompileUnit*)curr_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001525}
1526
1527bool
Greg Clayton96d7d742010-11-10 23:42:09 +00001528SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001529{
1530 sc.Clear();
1531 // Check if the symbol vendor already knows about this compile unit?
1532 sc.module_sp = m_obj_file->GetModule()->GetSP();
Greg Clayton96d7d742010-11-10 23:42:09 +00001533 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001534
1535 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1536 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001537 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001538
1539 return sc.function != NULL;
1540}
1541
1542uint32_t
1543SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1544{
1545 Timer scoped_timer(__PRETTY_FUNCTION__,
1546 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1547 so_addr.GetSection(),
1548 so_addr.GetOffset(),
1549 resolve_scope);
1550 uint32_t resolved = 0;
1551 if (resolve_scope & ( eSymbolContextCompUnit |
1552 eSymbolContextFunction |
1553 eSymbolContextBlock |
1554 eSymbolContextLineEntry))
1555 {
1556 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1557
1558 DWARFDebugAranges* debug_aranges = DebugAranges();
1559 DWARFDebugInfo* debug_info = DebugInfo();
1560 if (debug_aranges)
1561 {
1562 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1563 if (cu_offset != DW_INVALID_OFFSET)
1564 {
1565 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001566 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1567 if (curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001568 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001569 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001570 assert(sc.comp_unit != NULL);
1571 resolved |= eSymbolContextCompUnit;
1572
1573 if (resolve_scope & eSymbolContextLineEntry)
1574 {
1575 LineTable *line_table = sc.comp_unit->GetLineTable();
1576 if (line_table == NULL)
1577 {
1578 if (ParseCompileUnitLineTable(sc))
1579 line_table = sc.comp_unit->GetLineTable();
1580 }
1581 if (line_table != NULL)
1582 {
1583 if (so_addr.IsLinkedAddress())
1584 {
1585 Address linked_addr (so_addr);
1586 linked_addr.ResolveLinkedAddress();
1587 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1588 {
1589 resolved |= eSymbolContextLineEntry;
1590 }
1591 }
1592 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1593 {
1594 resolved |= eSymbolContextLineEntry;
1595 }
1596 }
1597 }
1598
1599 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1600 {
1601 DWARFDebugInfoEntry *function_die = NULL;
1602 DWARFDebugInfoEntry *block_die = NULL;
1603 if (resolve_scope & eSymbolContextBlock)
1604 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001605 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001606 }
1607 else
1608 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001609 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001610 }
1611
1612 if (function_die != NULL)
1613 {
1614 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1615 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001616 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001617 }
1618
1619 if (sc.function != NULL)
1620 {
1621 resolved |= eSymbolContextFunction;
1622
1623 if (resolve_scope & eSymbolContextBlock)
1624 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001625 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001626
1627 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001628 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001629 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001630 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001631 if (sc.block)
1632 resolved |= eSymbolContextBlock;
1633 }
1634 }
1635 }
1636 }
1637 }
1638 }
1639 }
1640 return resolved;
1641}
1642
1643
1644
1645uint32_t
1646SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1647{
1648 const uint32_t prev_size = sc_list.GetSize();
1649 if (resolve_scope & eSymbolContextCompUnit)
1650 {
1651 DWARFDebugInfo* debug_info = DebugInfo();
1652 if (debug_info)
1653 {
1654 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001655 DWARFCompileUnit* curr_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001656
Greg Clayton96d7d742010-11-10 23:42:09 +00001657 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001658 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001659 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001660 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1661 if (check_inlines || file_spec_matches_cu_file_spec)
1662 {
1663 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton96d7d742010-11-10 23:42:09 +00001664 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001665 assert(sc.comp_unit != NULL);
1666
1667 uint32_t file_idx = UINT32_MAX;
1668
1669 // If we are looking for inline functions only and we don't
1670 // find it in the support files, we are done.
1671 if (check_inlines)
1672 {
1673 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1674 if (file_idx == UINT32_MAX)
1675 continue;
1676 }
1677
1678 if (line != 0)
1679 {
1680 LineTable *line_table = sc.comp_unit->GetLineTable();
1681
1682 if (line_table != NULL && line != 0)
1683 {
1684 // We will have already looked up the file index if
1685 // we are searching for inline entries.
1686 if (!check_inlines)
1687 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1688
1689 if (file_idx != UINT32_MAX)
1690 {
1691 uint32_t found_line;
1692 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1693 found_line = sc.line_entry.line;
1694
Greg Clayton016a95e2010-09-14 02:20:48 +00001695 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001696 {
1697 sc.function = NULL;
1698 sc.block = NULL;
1699 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1700 {
1701 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1702 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1703 {
1704 DWARFDebugInfoEntry *function_die = NULL;
1705 DWARFDebugInfoEntry *block_die = NULL;
Greg Clayton96d7d742010-11-10 23:42:09 +00001706 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001707
1708 if (function_die != NULL)
1709 {
1710 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1711 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001712 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001713 }
1714
1715 if (sc.function != NULL)
1716 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001717 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001718
1719 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001720 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001721 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001722 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001723 }
1724 }
1725 }
1726
1727 sc_list.Append(sc);
1728 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1729 }
1730 }
1731 }
1732 else if (file_spec_matches_cu_file_spec && !check_inlines)
1733 {
1734 // only append the context if we aren't looking for inline call sites
1735 // by file and line and if the file spec matches that of the compile unit
1736 sc_list.Append(sc);
1737 }
1738 }
1739 else if (file_spec_matches_cu_file_spec && !check_inlines)
1740 {
1741 // only append the context if we aren't looking for inline call sites
1742 // by file and line and if the file spec matches that of the compile unit
1743 sc_list.Append(sc);
1744 }
1745
1746 if (!check_inlines)
1747 break;
1748 }
1749 }
1750 }
1751 }
1752 return sc_list.GetSize() - prev_size;
1753}
1754
1755void
1756SymbolFileDWARF::Index ()
1757{
1758 if (m_indexed)
1759 return;
1760 m_indexed = true;
1761 Timer scoped_timer (__PRETTY_FUNCTION__,
1762 "SymbolFileDWARF::Index (%s)",
1763 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1764
1765 DWARFDebugInfo* debug_info = DebugInfo();
1766 if (debug_info)
1767 {
Greg Clayton016a95e2010-09-14 02:20:48 +00001768 m_aranges.reset(new DWARFDebugAranges());
1769
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001770 uint32_t cu_idx = 0;
1771 const uint32_t num_compile_units = GetNumCompileUnits();
1772 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1773 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001774 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001775
Greg Clayton96d7d742010-11-10 23:42:09 +00001776 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001777
Greg Clayton96d7d742010-11-10 23:42:09 +00001778 curr_cu->Index (cu_idx,
Greg Claytonc685f8e2010-09-15 04:15:46 +00001779 m_function_basename_index,
1780 m_function_fullname_index,
1781 m_function_method_index,
1782 m_function_selector_index,
Greg Clayton450e3f32010-10-12 02:24:53 +00001783 m_objc_class_selectors_index,
Greg Claytonc685f8e2010-09-15 04:15:46 +00001784 m_global_index,
Greg Clayton69b04882010-10-15 02:03:22 +00001785 m_type_index,
1786 m_namespace_index,
Greg Clayton016a95e2010-09-14 02:20:48 +00001787 DebugRanges(),
1788 m_aranges.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001789
1790 // Keep memory down by clearing DIEs if this generate function
1791 // caused them to be parsed
1792 if (clear_dies)
Greg Clayton96d7d742010-11-10 23:42:09 +00001793 curr_cu->ClearDIEs (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001794 }
1795
Greg Clayton016a95e2010-09-14 02:20:48 +00001796 m_aranges->Sort();
Greg Claytonc685f8e2010-09-15 04:15:46 +00001797
Greg Clayton24739922010-10-13 03:15:28 +00001798#if defined (ENABLE_DEBUG_PRINTF)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001799 StreamFile s(stdout);
Greg Clayton24739922010-10-13 03:15:28 +00001800 s.Printf ("DWARF index for (%s) '%s/%s':",
1801 GetObjectFile()->GetModule()->GetArchitecture().AsCString(),
1802 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
1803 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
Greg Claytonba2d22d2010-11-13 22:57:37 +00001804 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
1805 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
1806 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
1807 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
1808 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
1809 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00001810 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Greg Claytonba2d22d2010-11-13 22:57:37 +00001811 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001812#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001813 }
1814}
1815
1816uint32_t
1817SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1818{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001819 DWARFDebugInfo* info = DebugInfo();
1820 if (info == NULL)
1821 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001822
1823 // If we aren't appending the results to this list, then clear the list
1824 if (!append)
1825 variables.Clear();
1826
1827 // Remember how many variables are in the list before we search in case
1828 // we are appending the results to a variable list.
1829 const uint32_t original_size = variables.GetSize();
1830
1831 // Index the DWARF if we haven't already
1832 if (!m_indexed)
1833 Index ();
1834
Greg Claytonc685f8e2010-09-15 04:15:46 +00001835 SymbolContext sc;
1836 sc.module_sp = m_obj_file->GetModule()->GetSP();
1837 assert (sc.module_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001838
Greg Clayton96d7d742010-11-10 23:42:09 +00001839 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001840 DWARFCompileUnit* prev_cu = NULL;
1841 const DWARFDebugInfoEntry* die = NULL;
1842 std::vector<NameToDIE::Info> die_info_array;
1843 const size_t num_matches = m_global_index.Find(name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001844 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001845 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001846 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001847
Greg Clayton96d7d742010-11-10 23:42:09 +00001848 if (curr_cu != prev_cu)
1849 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001850
Greg Clayton96d7d742010-11-10 23:42:09 +00001851 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001852
Greg Clayton96d7d742010-11-10 23:42:09 +00001853 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001854 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001855
Greg Clayton96d7d742010-11-10 23:42:09 +00001856 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001857
1858 if (variables.GetSize() - original_size >= max_matches)
1859 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001860 }
1861
1862 // Return the number of variable that were appended to the list
1863 return variables.GetSize() - original_size;
1864}
1865
1866uint32_t
1867SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1868{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001869 DWARFDebugInfo* info = DebugInfo();
1870 if (info == NULL)
1871 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001872
1873 // If we aren't appending the results to this list, then clear the list
1874 if (!append)
1875 variables.Clear();
1876
1877 // Remember how many variables are in the list before we search in case
1878 // we are appending the results to a variable list.
1879 const uint32_t original_size = variables.GetSize();
1880
1881 // Index the DWARF if we haven't already
1882 if (!m_indexed)
1883 Index ();
1884
Greg Claytonc685f8e2010-09-15 04:15:46 +00001885 SymbolContext sc;
1886 sc.module_sp = m_obj_file->GetModule()->GetSP();
1887 assert (sc.module_sp);
1888
Greg Clayton96d7d742010-11-10 23:42:09 +00001889 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001890 DWARFCompileUnit* prev_cu = NULL;
1891 const DWARFDebugInfoEntry* die = NULL;
1892 std::vector<NameToDIE::Info> die_info_array;
1893 const size_t num_matches = m_global_index.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001894 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001895 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001896 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001897
Greg Clayton96d7d742010-11-10 23:42:09 +00001898 if (curr_cu != prev_cu)
1899 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001900
Greg Clayton96d7d742010-11-10 23:42:09 +00001901 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001902
Greg Clayton96d7d742010-11-10 23:42:09 +00001903 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001904 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001905
Greg Clayton96d7d742010-11-10 23:42:09 +00001906 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001907
Greg Claytonc685f8e2010-09-15 04:15:46 +00001908 if (variables.GetSize() - original_size >= max_matches)
1909 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001910 }
1911
1912 // Return the number of variable that were appended to the list
1913 return variables.GetSize() - original_size;
1914}
1915
1916
Greg Clayton0c5cd902010-06-28 21:30:43 +00001917void
1918SymbolFileDWARF::FindFunctions
1919(
1920 const ConstString &name,
Greg Claytonc685f8e2010-09-15 04:15:46 +00001921 const NameToDIE &name_to_die,
Greg Clayton0c5cd902010-06-28 21:30:43 +00001922 SymbolContextList& sc_list
1923)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001924{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001925 DWARFDebugInfo* info = DebugInfo();
1926 if (info == NULL)
1927 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001928
Greg Claytonc685f8e2010-09-15 04:15:46 +00001929 SymbolContext sc;
1930 sc.module_sp = m_obj_file->GetModule()->GetSP();
1931 assert (sc.module_sp);
1932
Greg Clayton96d7d742010-11-10 23:42:09 +00001933 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001934 DWARFCompileUnit* prev_cu = NULL;
1935 const DWARFDebugInfoEntry* die = NULL;
1936 std::vector<NameToDIE::Info> die_info_array;
Greg Claytond7e05462010-11-14 00:22:48 +00001937 const size_t num_matches = name_to_die.Find (name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001938 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001939 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001940 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001941
Greg Clayton96d7d742010-11-10 23:42:09 +00001942 if (curr_cu != prev_cu)
1943 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001944
Greg Clayton96d7d742010-11-10 23:42:09 +00001945 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytond7e05462010-11-14 00:22:48 +00001946
1947 const DWARFDebugInfoEntry* inlined_die = NULL;
1948 if (die->Tag() == DW_TAG_inlined_subroutine)
1949 {
1950 inlined_die = die;
1951
1952 while ((die = die->GetParent()) != NULL)
1953 {
1954 if (die->Tag() == DW_TAG_subprogram)
1955 break;
1956 }
1957 }
1958 assert (die->Tag() == DW_TAG_subprogram);
Greg Clayton96d7d742010-11-10 23:42:09 +00001959 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00001960 {
Greg Claytond7e05462010-11-14 00:22:48 +00001961 Address addr;
1962 // Parse all blocks if needed
1963 if (inlined_die)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001964 {
Greg Claytond7e05462010-11-14 00:22:48 +00001965 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
1966 assert (sc.block != NULL);
1967 if (sc.block->GetStartAddress (addr) == false)
1968 addr.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001969 }
Greg Claytond7e05462010-11-14 00:22:48 +00001970 else
1971 {
1972 sc.block = NULL;
1973 addr = sc.function->GetAddressRange().GetBaseAddress();
1974 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00001975
Greg Claytond7e05462010-11-14 00:22:48 +00001976 if (addr.IsValid())
1977 {
1978
1979 // We found the function, so we should find the line table
1980 // and line table entry as well
1981 LineTable *line_table = sc.comp_unit->GetLineTable();
1982 if (line_table == NULL)
1983 {
1984 if (ParseCompileUnitLineTable(sc))
1985 line_table = sc.comp_unit->GetLineTable();
1986 }
1987 if (line_table != NULL)
1988 line_table->FindLineEntryByAddress (addr, sc.line_entry);
1989
1990 sc_list.Append(sc);
1991 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001992 }
1993 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00001994}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001995
Greg Claytonc685f8e2010-09-15 04:15:46 +00001996
1997void
1998SymbolFileDWARF::FindFunctions
1999(
2000 const RegularExpression &regex,
2001 const NameToDIE &name_to_die,
2002 SymbolContextList& sc_list
2003)
2004{
2005 DWARFDebugInfo* info = DebugInfo();
2006 if (info == NULL)
2007 return;
2008
2009 SymbolContext sc;
2010 sc.module_sp = m_obj_file->GetModule()->GetSP();
2011 assert (sc.module_sp);
2012
Greg Clayton96d7d742010-11-10 23:42:09 +00002013 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002014 DWARFCompileUnit* prev_cu = NULL;
2015 const DWARFDebugInfoEntry* die = NULL;
2016 std::vector<NameToDIE::Info> die_info_array;
2017 const size_t num_matches = name_to_die.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002018 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002019 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002020 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002021
Greg Clayton96d7d742010-11-10 23:42:09 +00002022 if (curr_cu != prev_cu)
2023 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002024
Greg Clayton96d7d742010-11-10 23:42:09 +00002025 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2026 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00002027 {
2028 // We found the function, so we should find the line table
2029 // and line table entry as well
2030 LineTable *line_table = sc.comp_unit->GetLineTable();
2031 if (line_table == NULL)
2032 {
2033 if (ParseCompileUnitLineTable(sc))
2034 line_table = sc.comp_unit->GetLineTable();
2035 }
2036 if (line_table != NULL)
2037 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
2038
2039 sc_list.Append(sc);
2040 }
2041 }
Greg Clayton0c5cd902010-06-28 21:30:43 +00002042}
2043
2044uint32_t
2045SymbolFileDWARF::FindFunctions
2046(
2047 const ConstString &name,
2048 uint32_t name_type_mask,
2049 bool append,
2050 SymbolContextList& sc_list
2051)
2052{
2053 Timer scoped_timer (__PRETTY_FUNCTION__,
2054 "SymbolFileDWARF::FindFunctions (name = '%s')",
2055 name.AsCString());
2056
Greg Clayton0c5cd902010-06-28 21:30:43 +00002057 // If we aren't appending the results to this list, then clear the list
2058 if (!append)
2059 sc_list.Clear();
2060
2061 // Remember how many sc_list are in the list before we search in case
2062 // we are appending the results to a variable list.
2063 uint32_t original_size = sc_list.GetSize();
2064
2065 // Index the DWARF if we haven't already
2066 if (!m_indexed)
2067 Index ();
2068
2069 if (name_type_mask & eFunctionNameTypeBase)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002070 FindFunctions (name, m_function_basename_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002071
2072 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002073 FindFunctions (name, m_function_fullname_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002074
2075 if (name_type_mask & eFunctionNameTypeMethod)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002076 FindFunctions (name, m_function_method_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002077
2078 if (name_type_mask & eFunctionNameTypeSelector)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002079 FindFunctions (name, m_function_selector_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002080
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002081 // Return the number of variable that were appended to the list
2082 return sc_list.GetSize() - original_size;
2083}
2084
2085
2086uint32_t
2087SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2088{
2089 Timer scoped_timer (__PRETTY_FUNCTION__,
2090 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2091 regex.GetText());
2092
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002093 // If we aren't appending the results to this list, then clear the list
2094 if (!append)
2095 sc_list.Clear();
2096
2097 // Remember how many sc_list are in the list before we search in case
2098 // we are appending the results to a variable list.
2099 uint32_t original_size = sc_list.GetSize();
2100
2101 // Index the DWARF if we haven't already
2102 if (!m_indexed)
2103 Index ();
2104
Greg Claytonc685f8e2010-09-15 04:15:46 +00002105 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002106
Greg Claytonc685f8e2010-09-15 04:15:46 +00002107 FindFunctions (regex, m_function_fullname_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002108
2109 // Return the number of variable that were appended to the list
2110 return sc_list.GetSize() - original_size;
2111}
2112
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002113uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002114SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002115{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002116 DWARFDebugInfo* info = DebugInfo();
2117 if (info == NULL)
2118 return 0;
2119
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002120 // If we aren't appending the results to this list, then clear the list
2121 if (!append)
2122 types.Clear();
2123
Greg Clayton6dbd3982010-09-15 05:51:24 +00002124 // Index if we already haven't to make sure the compile units
2125 // get indexed and make their global DIE index list
2126 if (!m_indexed)
2127 Index ();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002128
Greg Claytonc685f8e2010-09-15 04:15:46 +00002129 const uint32_t initial_types_size = types.GetSize();
Greg Clayton96d7d742010-11-10 23:42:09 +00002130 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002131 DWARFCompileUnit* prev_cu = NULL;
2132 const DWARFDebugInfoEntry* die = NULL;
2133 std::vector<NameToDIE::Info> die_info_array;
Greg Clayton69b04882010-10-15 02:03:22 +00002134 const size_t num_matches = m_type_index.Find (name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002135 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002136 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002137 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002138
Greg Clayton96d7d742010-11-10 23:42:09 +00002139 if (curr_cu != prev_cu)
2140 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002141
Greg Clayton96d7d742010-11-10 23:42:09 +00002142 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002143
Greg Clayton96d7d742010-11-10 23:42:09 +00002144 Type *matching_type = ResolveType (curr_cu, die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002145 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002146 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00002147 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002148 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonc685f8e2010-09-15 04:15:46 +00002149 assert (type_sp.get() != NULL);
2150 types.InsertUnique (type_sp);
2151 if (types.GetSize() >= max_matches)
2152 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002153 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002154 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002155 return types.GetSize() - initial_types_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002156}
2157
2158
Greg Clayton526e5af2010-11-13 03:52:47 +00002159ClangNamespaceDecl
Greg Clayton96d7d742010-11-10 23:42:09 +00002160SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
2161 const ConstString &name)
2162{
Greg Clayton526e5af2010-11-13 03:52:47 +00002163 ClangNamespaceDecl namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002164 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00002165 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00002166 {
Greg Clayton526e5af2010-11-13 03:52:47 +00002167 // Index if we already haven't to make sure the compile units
2168 // get indexed and make their global DIE index list
2169 if (!m_indexed)
2170 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00002171
Greg Clayton526e5af2010-11-13 03:52:47 +00002172 DWARFCompileUnit* curr_cu = NULL;
2173 DWARFCompileUnit* prev_cu = NULL;
2174 const DWARFDebugInfoEntry* die = NULL;
2175 std::vector<NameToDIE::Info> die_info_array;
2176 const size_t num_matches = m_namespace_index.Find (name, die_info_array);
2177 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
2178 {
2179 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2180
2181 if (curr_cu != prev_cu)
2182 curr_cu->ExtractDIEsIfNeeded (false);
Greg Clayton96d7d742010-11-10 23:42:09 +00002183
Greg Clayton526e5af2010-11-13 03:52:47 +00002184 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2185
2186 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (curr_cu, die);
2187 if (clang_namespace_decl)
2188 {
2189 namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
2190 namespace_decl.SetNamespaceDecl (clang_namespace_decl);
2191 }
2192 }
Greg Clayton96d7d742010-11-10 23:42:09 +00002193 }
Greg Clayton526e5af2010-11-13 03:52:47 +00002194 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002195}
2196
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002197uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002198SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002199{
2200 // Remember how many sc_list are in the list before we search in case
2201 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002202 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002203
2204 const uint32_t num_die_offsets = die_offsets.size();
2205 // Parse all of the types we found from the pubtypes matches
2206 uint32_t i;
2207 uint32_t num_matches = 0;
2208 for (i = 0; i < num_die_offsets; ++i)
2209 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002210 Type *matching_type = ResolveTypeUID (die_offsets[i]);
2211 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002212 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002213 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002214 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002215 assert (type_sp.get() != NULL);
2216 types.InsertUnique (type_sp);
2217 ++num_matches;
2218 if (num_matches >= max_matches)
2219 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002220 }
2221 }
2222
2223 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002224 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002225}
2226
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002227
2228size_t
2229SymbolFileDWARF::ParseChildParameters
2230(
2231 const SymbolContext& sc,
2232 TypeSP& type_sp,
Greg Clayton0fffff52010-09-24 05:15:53 +00002233 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002234 const DWARFDebugInfoEntry *parent_die,
Greg Claytona51ed9b2010-09-23 01:09:21 +00002235 bool skip_artificial,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002236 TypeList* type_list,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002237 std::vector<clang_type_t>& function_param_types,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002238 std::vector<clang::ParmVarDecl*>& function_param_decls
2239)
2240{
2241 if (parent_die == NULL)
2242 return 0;
2243
Greg Claytond88d7592010-09-15 08:33:30 +00002244 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2245
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002246 size_t count = 0;
2247 const DWARFDebugInfoEntry *die;
2248 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2249 {
2250 dw_tag_t tag = die->Tag();
2251 switch (tag)
2252 {
2253 case DW_TAG_formal_parameter:
2254 {
2255 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002256 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002257 if (num_attributes > 0)
2258 {
2259 const char *name = NULL;
2260 Declaration decl;
2261 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002262 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002263 // one of None, Auto, Register, Extern, Static, PrivateExtern
2264
Sean Callanane2ef6e32010-09-23 03:01:22 +00002265 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002266 uint32_t i;
2267 for (i=0; i<num_attributes; ++i)
2268 {
2269 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2270 DWARFFormValue form_value;
2271 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2272 {
2273 switch (attr)
2274 {
2275 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2276 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2277 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2278 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2279 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002280 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002281 case DW_AT_location:
2282 // if (form_value.BlockData())
2283 // {
2284 // const DataExtractor& debug_info_data = debug_info();
2285 // uint32_t block_length = form_value.Unsigned();
2286 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2287 // }
2288 // else
2289 // {
2290 // }
2291 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002292 case DW_AT_const_value:
2293 case DW_AT_default_value:
2294 case DW_AT_description:
2295 case DW_AT_endianity:
2296 case DW_AT_is_optional:
2297 case DW_AT_segment:
2298 case DW_AT_variable_parameter:
2299 default:
2300 case DW_AT_abstract_origin:
2301 case DW_AT_sibling:
2302 break;
2303 }
2304 }
2305 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00002306
Greg Clayton0fffff52010-09-24 05:15:53 +00002307 bool skip = false;
2308 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002309 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002310 if (is_artificial)
2311 skip = true;
2312 else
2313 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002314
Greg Clayton0fffff52010-09-24 05:15:53 +00002315 // HACK: Objective C formal parameters "self" and "_cmd"
2316 // are not marked as artificial in the DWARF...
Greg Clayton96d7d742010-11-10 23:42:09 +00002317 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2318 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
Greg Clayton0fffff52010-09-24 05:15:53 +00002319 {
2320 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2321 skip = true;
2322 }
2323 }
2324 }
2325
2326 if (!skip)
2327 {
2328 Type *type = ResolveTypeUID(param_type_die_offset);
2329 if (type)
2330 {
Greg Claytonc93237c2010-10-01 20:48:32 +00002331 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00002332
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002333 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00002334 assert(param_var_decl);
2335 function_param_decls.push_back(param_var_decl);
2336 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002337 }
2338 }
2339 }
2340 break;
2341
2342 default:
2343 break;
2344 }
2345 }
2346 return count;
2347}
2348
2349size_t
2350SymbolFileDWARF::ParseChildEnumerators
2351(
2352 const SymbolContext& sc,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002353 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002354 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00002355 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002356 const DWARFDebugInfoEntry *parent_die
2357)
2358{
2359 if (parent_die == NULL)
2360 return 0;
2361
2362 size_t enumerators_added = 0;
2363 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002364 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2365
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002366 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2367 {
2368 const dw_tag_t tag = die->Tag();
2369 if (tag == DW_TAG_enumerator)
2370 {
2371 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002372 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002373 if (num_child_attributes > 0)
2374 {
2375 const char *name = NULL;
2376 bool got_value = false;
2377 int64_t enum_value = 0;
2378 Declaration decl;
2379
2380 uint32_t i;
2381 for (i=0; i<num_child_attributes; ++i)
2382 {
2383 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2384 DWARFFormValue form_value;
2385 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2386 {
2387 switch (attr)
2388 {
2389 case DW_AT_const_value:
2390 got_value = true;
2391 enum_value = form_value.Unsigned();
2392 break;
2393
2394 case DW_AT_name:
2395 name = form_value.AsCString(&get_debug_str_data());
2396 break;
2397
2398 case DW_AT_description:
2399 default:
2400 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2401 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2402 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2403 case DW_AT_sibling:
2404 break;
2405 }
2406 }
2407 }
2408
2409 if (name && name[0] && got_value)
2410 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002411 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2412 enumerator_clang_type,
2413 decl,
2414 name,
2415 enum_value,
2416 enumerator_byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002417 ++enumerators_added;
2418 }
2419 }
2420 }
2421 }
2422 return enumerators_added;
2423}
2424
2425void
2426SymbolFileDWARF::ParseChildArrayInfo
2427(
2428 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00002429 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002430 const DWARFDebugInfoEntry *parent_die,
2431 int64_t& first_index,
2432 std::vector<uint64_t>& element_orders,
2433 uint32_t& byte_stride,
2434 uint32_t& bit_stride
2435)
2436{
2437 if (parent_die == NULL)
2438 return;
2439
2440 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002441 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002442 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2443 {
2444 const dw_tag_t tag = die->Tag();
2445 switch (tag)
2446 {
2447 case DW_TAG_enumerator:
2448 {
2449 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002450 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002451 if (num_child_attributes > 0)
2452 {
2453 const char *name = NULL;
2454 bool got_value = false;
2455 int64_t enum_value = 0;
2456
2457 uint32_t i;
2458 for (i=0; i<num_child_attributes; ++i)
2459 {
2460 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2461 DWARFFormValue form_value;
2462 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2463 {
2464 switch (attr)
2465 {
2466 case DW_AT_const_value:
2467 got_value = true;
2468 enum_value = form_value.Unsigned();
2469 break;
2470
2471 case DW_AT_name:
2472 name = form_value.AsCString(&get_debug_str_data());
2473 break;
2474
2475 case DW_AT_description:
2476 default:
2477 case DW_AT_decl_file:
2478 case DW_AT_decl_line:
2479 case DW_AT_decl_column:
2480 case DW_AT_sibling:
2481 break;
2482 }
2483 }
2484 }
2485 }
2486 }
2487 break;
2488
2489 case DW_TAG_subrange_type:
2490 {
2491 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002492 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002493 if (num_child_attributes > 0)
2494 {
2495 const char *name = NULL;
2496 bool got_value = false;
2497 uint64_t byte_size = 0;
2498 int64_t enum_value = 0;
2499 uint64_t num_elements = 0;
2500 uint64_t lower_bound = 0;
2501 uint64_t upper_bound = 0;
2502 uint32_t i;
2503 for (i=0; i<num_child_attributes; ++i)
2504 {
2505 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2506 DWARFFormValue form_value;
2507 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2508 {
2509 switch (attr)
2510 {
2511 case DW_AT_const_value:
2512 got_value = true;
2513 enum_value = form_value.Unsigned();
2514 break;
2515
2516 case DW_AT_name:
2517 name = form_value.AsCString(&get_debug_str_data());
2518 break;
2519
2520 case DW_AT_count:
2521 num_elements = form_value.Unsigned();
2522 break;
2523
2524 case DW_AT_bit_stride:
2525 bit_stride = form_value.Unsigned();
2526 break;
2527
2528 case DW_AT_byte_stride:
2529 byte_stride = form_value.Unsigned();
2530 break;
2531
2532 case DW_AT_byte_size:
2533 byte_size = form_value.Unsigned();
2534 break;
2535
2536 case DW_AT_lower_bound:
2537 lower_bound = form_value.Unsigned();
2538 break;
2539
2540 case DW_AT_upper_bound:
2541 upper_bound = form_value.Unsigned();
2542 break;
2543
2544 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002545 case DW_AT_abstract_origin:
2546 case DW_AT_accessibility:
2547 case DW_AT_allocated:
2548 case DW_AT_associated:
2549 case DW_AT_data_location:
2550 case DW_AT_declaration:
2551 case DW_AT_description:
2552 case DW_AT_sibling:
2553 case DW_AT_threads_scaled:
2554 case DW_AT_type:
2555 case DW_AT_visibility:
2556 break;
2557 }
2558 }
2559 }
2560
2561 if (upper_bound > lower_bound)
2562 num_elements = upper_bound - lower_bound + 1;
2563
2564 if (num_elements > 0)
2565 element_orders.push_back (num_elements);
2566 }
2567 }
2568 break;
2569 }
2570 }
2571}
2572
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002573TypeSP
Greg Clayton96d7d742010-11-10 23:42:09 +00002574SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002575{
2576 TypeSP type_sp;
2577 if (die != NULL)
2578 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002579 assert(curr_cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00002580 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002581 if (type_ptr == NULL)
2582 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002583 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
2584 type_sp = ParseType(sc, curr_cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002585 }
2586 else if (type_ptr != DIE_IS_BEING_PARSED)
2587 {
2588 // Grab the existing type from the master types lists
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002589 type_sp = GetTypeList()->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002590 }
2591
2592 }
2593 return type_sp;
2594}
2595
2596clang::DeclContext *
2597SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2598{
2599 if (die_offset != DW_INVALID_OFFSET)
2600 {
2601 DWARFCompileUnitSP cu_sp;
2602 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2603 return GetClangDeclContextForDIE (cu_sp.get(), die);
2604 }
2605 return NULL;
2606}
2607
2608
Greg Clayton96d7d742010-11-10 23:42:09 +00002609clang::NamespaceDecl *
2610SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2611{
2612 if (die->Tag() == DW_TAG_namespace)
2613 {
2614 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2615 if (namespace_name)
2616 {
2617 Declaration decl; // TODO: fill in the decl object
2618 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent()));
2619 if (namespace_decl)
2620 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2621 return namespace_decl;
2622 }
2623 }
2624 return NULL;
2625}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002626
2627clang::DeclContext *
Greg Clayton96d7d742010-11-10 23:42:09 +00002628SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002629{
2630 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2631 if (pos != m_die_to_decl_ctx.end())
2632 return pos->second;
2633
2634 while (die != NULL)
2635 {
2636 switch (die->Tag())
2637 {
2638 case DW_TAG_namespace:
2639 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002640 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002641 if (namespace_name)
2642 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002643 Declaration decl; // TODO: fill in the decl object
Greg Clayton96d7d742010-11-10 23:42:09 +00002644 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002645 if (namespace_decl)
2646 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2647 return namespace_decl;
2648 }
2649 }
2650 break;
2651
2652 default:
2653 break;
2654 }
2655 clang::DeclContext *decl_ctx;
Greg Clayton96d7d742010-11-10 23:42:09 +00002656 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002657 if (decl_ctx)
2658 return decl_ctx;
2659
Greg Clayton96d7d742010-11-10 23:42:09 +00002660 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002661 if (decl_ctx)
2662 return decl_ctx;
2663
2664 die = die->GetParent();
2665 }
Greg Clayton7a345282010-11-09 23:46:37 +00002666 // Right now we have only one translation unit per module...
2667 if (m_clang_tu_decl == NULL)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002668 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Greg Clayton7a345282010-11-09 23:46:37 +00002669 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002670}
2671
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002672// This function can be used when a DIE is found that is a forward declaration
2673// DIE and we want to try and find a type that has the complete definition.
2674TypeSP
2675SymbolFileDWARF::FindDefinitionTypeForDIE (
Greg Clayton96d7d742010-11-10 23:42:09 +00002676 DWARFCompileUnit* curr_cu,
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002677 const DWARFDebugInfoEntry *die,
2678 const ConstString &type_name
2679)
2680{
2681 TypeSP type_sp;
2682
Greg Clayton96d7d742010-11-10 23:42:09 +00002683 if (curr_cu == NULL || die == NULL || !type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002684 return type_sp;
2685
2686 const dw_tag_t type_tag = die->Tag();
2687 std::vector<NameToDIE::Info> die_info_array;
2688 const size_t num_matches = m_type_index.Find (type_name, die_info_array);
2689 if (num_matches > 0)
2690 {
2691 DWARFCompileUnit* type_cu = NULL;
Greg Clayton96d7d742010-11-10 23:42:09 +00002692 DWARFCompileUnit* curr_cu = curr_cu;
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002693 DWARFDebugInfo *info = DebugInfo();
2694 for (size_t i=0; i<num_matches; ++i)
2695 {
2696 type_cu = info->GetCompileUnitAtIndex (die_info_array[i].cu_idx);
2697
2698 if (type_cu != curr_cu)
2699 {
2700 type_cu->ExtractDIEsIfNeeded (false);
2701 curr_cu = type_cu;
2702 }
2703
2704 DWARFDebugInfoEntry *type_die = type_cu->GetDIEAtIndexUnchecked (die_info_array[i].die_idx);
2705
2706 if (type_die != die && type_die->Tag() == type_tag)
2707 {
2708 // Hold off on comparing parent DIE tags until
2709 // we know what happens with stuff in namespaces
2710 // for gcc and clang...
2711 //DWARFDebugInfoEntry *parent_die = die->GetParent();
2712 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
2713 //if (parent_die->Tag() == parent_type_die->Tag())
2714 {
2715 Type *resolved_type = ResolveType (type_cu, type_die, false);
2716 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
2717 {
2718 DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n",
2719 die->GetOffset(),
Greg Clayton96d7d742010-11-10 23:42:09 +00002720 curr_cu->GetOffset(),
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002721 m_obj_file->GetFileSpec().GetFilename().AsCString(),
2722 type_die->GetOffset(),
2723 type_cu->GetOffset());
2724
2725 m_die_to_type[die] = resolved_type;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002726 type_sp = GetTypeList()->FindType(resolved_type->GetID());
Greg Clayton40328bf2010-11-08 02:05:08 +00002727 if (!type_sp)
2728 {
2729 DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset());
2730 }
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002731 break;
2732 }
2733 }
2734 }
2735 }
2736 }
2737 return type_sp;
2738}
2739
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002740TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00002741SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002742{
2743 TypeSP type_sp;
2744
Greg Clayton1be10fc2010-09-29 01:12:09 +00002745 if (type_is_new_ptr)
2746 *type_is_new_ptr = false;
2747
Sean Callananc7fbf732010-08-06 00:32:49 +00002748 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002749 if (die != NULL)
2750 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00002751 Type *type_ptr = m_die_to_type.lookup (die);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002752 TypeList* type_list = GetTypeList();
Greg Clayton594e5ed2010-09-27 21:07:38 +00002753 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002754 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002755 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00002756 if (type_is_new_ptr)
2757 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002758
Greg Clayton594e5ed2010-09-27 21:07:38 +00002759 const dw_tag_t tag = die->Tag();
2760
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002761 bool is_forward_declaration = false;
2762 DWARFDebugInfoEntry::Attributes attributes;
2763 const char *type_name_cstr = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00002764 ConstString type_name_const_str;
Greg Clayton526e5af2010-11-13 03:52:47 +00002765 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
2766 size_t byte_size = 0;
2767 Declaration decl;
2768
Greg Clayton4957bf62010-09-30 21:49:03 +00002769 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002770 clang_type_t clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002771
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002772 dw_attr_t attr;
2773
2774 switch (tag)
2775 {
2776 case DW_TAG_base_type:
2777 case DW_TAG_pointer_type:
2778 case DW_TAG_reference_type:
2779 case DW_TAG_typedef:
2780 case DW_TAG_const_type:
2781 case DW_TAG_restrict_type:
2782 case DW_TAG_volatile_type:
2783 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002784 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002785 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002786
Greg Claytond88d7592010-09-15 08:33:30 +00002787 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002788 uint32_t encoding = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002789 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
2790
2791 if (num_attributes > 0)
2792 {
2793 uint32_t i;
2794 for (i=0; i<num_attributes; ++i)
2795 {
2796 attr = attributes.AttributeAtIndex(i);
2797 DWARFFormValue form_value;
2798 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2799 {
2800 switch (attr)
2801 {
2802 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2803 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2804 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2805 case DW_AT_name:
2806 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00002807 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002808 break;
2809 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
2810 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
2811 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2812 default:
2813 case DW_AT_sibling:
2814 break;
2815 }
2816 }
2817 }
2818 }
2819
Greg Claytonc93237c2010-10-01 20:48:32 +00002820 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);
2821
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002822 switch (tag)
2823 {
2824 default:
Greg Clayton526e5af2010-11-13 03:52:47 +00002825 break;
2826
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002827 case DW_TAG_base_type:
Greg Clayton526e5af2010-11-13 03:52:47 +00002828 resolve_state = Type::eResolveStateFull;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002829 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
2830 encoding,
2831 byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002832 break;
2833
Greg Clayton526e5af2010-11-13 03:52:47 +00002834 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
2835 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
2836 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
2837 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
2838 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
2839 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002840 }
2841
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002842 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
2843 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
2844 {
2845 static ConstString g_objc_type_name_id("id");
2846 static ConstString g_objc_type_name_Class("Class");
2847 static ConstString g_objc_type_name_selector("SEL");
2848
Greg Clayton24739922010-10-13 03:15:28 +00002849 if (type_name_const_str == g_objc_type_name_id)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002850 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002851 clang_type = ast.GetBuiltInType_objc_id();
Greg Clayton526e5af2010-11-13 03:52:47 +00002852 resolve_state = Type::eResolveStateFull;
2853
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002854 }
Greg Clayton24739922010-10-13 03:15:28 +00002855 else if (type_name_const_str == g_objc_type_name_Class)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002856 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002857 clang_type = ast.GetBuiltInType_objc_Class();
Greg Clayton526e5af2010-11-13 03:52:47 +00002858 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002859 }
Greg Clayton24739922010-10-13 03:15:28 +00002860 else if (type_name_const_str == g_objc_type_name_selector)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002861 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002862 clang_type = ast.GetBuiltInType_objc_selector();
Greg Clayton526e5af2010-11-13 03:52:47 +00002863 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002864 }
2865 }
2866
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002867 type_sp.reset( new Type (die->GetOffset(),
2868 this,
2869 type_name_const_str,
2870 byte_size,
2871 NULL,
2872 encoding_uid,
2873 encoding_data_type,
2874 &decl,
2875 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00002876 resolve_state));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002877
Greg Clayton594e5ed2010-09-27 21:07:38 +00002878 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002879
2880// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
2881// if (encoding_type != NULL)
2882// {
2883// if (encoding_type != DIE_IS_BEING_PARSED)
2884// type_sp->SetEncodingType(encoding_type);
2885// else
2886// m_indirect_fixups.push_back(type_sp.get());
2887// }
2888 }
2889 break;
2890
2891 case DW_TAG_structure_type:
2892 case DW_TAG_union_type:
2893 case DW_TAG_class_type:
2894 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002895 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002896 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002897
Greg Clayton9e409562010-07-28 02:04:09 +00002898 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002899 //bool struct_is_class = false;
Greg Claytond88d7592010-09-15 08:33:30 +00002900 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002901 if (num_attributes > 0)
2902 {
2903 uint32_t i;
2904 for (i=0; i<num_attributes; ++i)
2905 {
2906 attr = attributes.AttributeAtIndex(i);
2907 DWARFFormValue form_value;
2908 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2909 {
2910 switch (attr)
2911 {
Greg Clayton9e409562010-07-28 02:04:09 +00002912 case DW_AT_decl_file:
2913 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
2914 break;
2915
2916 case DW_AT_decl_line:
2917 decl.SetLine(form_value.Unsigned());
2918 break;
2919
2920 case DW_AT_decl_column:
2921 decl.SetColumn(form_value.Unsigned());
2922 break;
2923
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002924 case DW_AT_name:
2925 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00002926 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002927 break;
Greg Clayton9e409562010-07-28 02:04:09 +00002928
2929 case DW_AT_byte_size:
2930 byte_size = form_value.Unsigned();
2931 break;
2932
2933 case DW_AT_accessibility:
2934 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
2935 break;
2936
2937 case DW_AT_declaration:
Greg Clayton7a345282010-11-09 23:46:37 +00002938 is_forward_declaration = form_value.Unsigned() != 0;
Greg Clayton9e409562010-07-28 02:04:09 +00002939 break;
2940
2941 case DW_AT_APPLE_runtime_class:
2942 class_language = (LanguageType)form_value.Signed();
2943 break;
2944
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002945 case DW_AT_allocated:
2946 case DW_AT_associated:
2947 case DW_AT_data_location:
2948 case DW_AT_description:
2949 case DW_AT_start_scope:
2950 case DW_AT_visibility:
2951 default:
2952 case DW_AT_sibling:
2953 break;
2954 }
2955 }
2956 }
2957 }
2958
Greg Claytonc93237c2010-10-01 20:48:32 +00002959 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
2960
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002961 int tag_decl_kind = -1;
Sean Callananc7fbf732010-08-06 00:32:49 +00002962 AccessType default_accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002963 if (tag == DW_TAG_structure_type)
2964 {
2965 tag_decl_kind = clang::TTK_Struct;
Sean Callananc7fbf732010-08-06 00:32:49 +00002966 default_accessibility = eAccessPublic;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002967 }
2968 else if (tag == DW_TAG_union_type)
2969 {
2970 tag_decl_kind = clang::TTK_Union;
Sean Callananc7fbf732010-08-06 00:32:49 +00002971 default_accessibility = eAccessPublic;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002972 }
2973 else if (tag == DW_TAG_class_type)
2974 {
2975 tag_decl_kind = clang::TTK_Class;
Sean Callananc7fbf732010-08-06 00:32:49 +00002976 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002977 }
2978
Greg Clayton24739922010-10-13 03:15:28 +00002979
Greg Claytonc615ce42010-11-09 04:42:43 +00002980 if (is_forward_declaration)
2981 {
2982 // We have a forward declaration to a type and we need
2983 // to try and find a full declaration. We look in the
2984 // current type index just in case we have a forward
2985 // declaration followed by an actual declarations in the
2986 // DWARF. If this fails, we need to look elsewhere...
2987
2988 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
2989
2990 if (!type_sp)
2991 {
2992 // We weren't able to find a full declaration in
2993 // this DWARF, see if we have a declaration anywhere
2994 // else...
2995 if (m_debug_map_symfile)
2996 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
2997 }
2998 if (type_sp)
2999 return type_sp;
3000 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003001 assert (tag_decl_kind != -1);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003002 bool clang_type_was_created = false;
3003 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3004 if (clang_type == NULL)
3005 {
3006 clang_type_was_created = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003007 clang_type = ast.CreateRecordType (type_name_cstr,
3008 tag_decl_kind,
3009 GetClangDeclContextForDIE (dwarf_cu, die),
3010 class_language);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003011 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003012
Greg Clayton6adffa22010-09-28 01:04:25 +00003013 // Store a forward declaration to this class type in case any
3014 // parameters in any class methods need it for the clang
3015 // types for function prototypes.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003016 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003017 type_sp.reset (new Type (die->GetOffset(),
3018 this,
3019 type_name_const_str,
3020 byte_size,
3021 NULL,
3022 LLDB_INVALID_UID,
3023 Type::eEncodingIsUID,
3024 &decl,
3025 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003026 Type::eResolveStateForward));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003027
Greg Clayton594e5ed2010-09-27 21:07:38 +00003028 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003029
Greg Clayton40328bf2010-11-08 02:05:08 +00003030 if (die->HasChildren() == false && is_forward_declaration == false)
Greg Clayton1be10fc2010-09-29 01:12:09 +00003031 {
Greg Clayton4957bf62010-09-30 21:49:03 +00003032 // No children for this struct/union/class, lets finish it
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003033 ast.StartTagDeclarationDefinition (clang_type);
3034 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton4957bf62010-09-30 21:49:03 +00003035 }
3036 else if (clang_type_was_created)
3037 {
3038 // Leave this as a forward declaration until we need
3039 // to know the details of the type. lldb_private::Type
3040 // will automatically call the SymbolFile virtual function
3041 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3042 // When the definition needs to be defined.
Greg Clayton1be10fc2010-09-29 01:12:09 +00003043 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00003044 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003045 }
Greg Clayton4957bf62010-09-30 21:49:03 +00003046
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003047 }
3048 break;
3049
3050 case DW_TAG_enumeration_type:
3051 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003052 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003053 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003054
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003055 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003056
Greg Claytond88d7592010-09-15 08:33:30 +00003057 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003058 if (num_attributes > 0)
3059 {
3060 uint32_t i;
3061
3062 for (i=0; i<num_attributes; ++i)
3063 {
3064 attr = attributes.AttributeAtIndex(i);
3065 DWARFFormValue form_value;
3066 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3067 {
3068 switch (attr)
3069 {
Greg Clayton7a345282010-11-09 23:46:37 +00003070 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3071 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3072 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003073 case DW_AT_name:
3074 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003075 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003076 break;
Greg Clayton7a345282010-11-09 23:46:37 +00003077 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
3078 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3079 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3080 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003081 case DW_AT_allocated:
3082 case DW_AT_associated:
3083 case DW_AT_bit_stride:
3084 case DW_AT_byte_stride:
3085 case DW_AT_data_location:
3086 case DW_AT_description:
3087 case DW_AT_start_scope:
3088 case DW_AT_visibility:
3089 case DW_AT_specification:
3090 case DW_AT_abstract_origin:
3091 case DW_AT_sibling:
3092 break;
3093 }
3094 }
3095 }
3096
Greg Claytonc93237c2010-10-01 20:48:32 +00003097 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3098
Greg Clayton1be10fc2010-09-29 01:12:09 +00003099 clang_type_t enumerator_clang_type = NULL;
3100 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3101 if (clang_type == NULL)
3102 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003103 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
3104 DW_ATE_signed,
3105 byte_size * 8);
3106 clang_type = ast.CreateEnumerationType (decl,
3107 type_name_cstr,
3108 enumerator_clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003109 }
3110 else
3111 {
3112 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
3113 assert (enumerator_clang_type != NULL);
3114 }
3115
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003116 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003117 type_sp.reset( new Type (die->GetOffset(),
3118 this,
3119 type_name_const_str,
3120 byte_size,
3121 NULL,
3122 encoding_uid,
3123 Type::eEncodingIsUID,
3124 &decl,
3125 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003126 Type::eResolveStateForward));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003127
Greg Clayton594e5ed2010-09-27 21:07:38 +00003128 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003129
Greg Clayton1be10fc2010-09-29 01:12:09 +00003130 // Leave this as a forward declaration until we need
3131 // to know the details of the type. lldb_private::Type
3132 // will automatically call the SymbolFile virtual function
3133 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3134 // When the definition needs to be defined.
3135 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00003136 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003137
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003138 }
3139 }
3140 break;
3141
Jim Inghamb0be4422010-08-12 01:20:14 +00003142 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003143 case DW_TAG_subprogram:
3144 case DW_TAG_subroutine_type:
3145 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003146 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003147 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003148
3149 const char *mangled = NULL;
3150 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00003151 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003152 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003153 bool is_static = false;
3154 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00003155 bool is_explicit = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003156
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003157 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00003158 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003159
3160
Greg Claytond88d7592010-09-15 08:33:30 +00003161 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003162 if (num_attributes > 0)
3163 {
3164 uint32_t i;
3165 for (i=0; i<num_attributes; ++i)
3166 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003167 const dw_attr_t attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003168 DWARFFormValue form_value;
3169 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3170 {
3171 switch (attr)
3172 {
3173 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3174 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3175 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3176 case DW_AT_name:
3177 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003178 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003179 break;
3180
3181 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
3182 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003183 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003184 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003185 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
3186 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Claytonf51de672010-10-01 02:31:07 +00003187 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
3188
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003189 case DW_AT_external:
3190 if (form_value.Unsigned())
3191 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00003192 if (storage == clang::SC_None)
3193 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003194 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00003195 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003196 }
3197 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003198
3199 case DW_AT_allocated:
3200 case DW_AT_associated:
3201 case DW_AT_address_class:
3202 case DW_AT_artificial:
3203 case DW_AT_calling_convention:
3204 case DW_AT_data_location:
3205 case DW_AT_elemental:
3206 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003207 case DW_AT_frame_base:
3208 case DW_AT_high_pc:
3209 case DW_AT_low_pc:
3210 case DW_AT_object_pointer:
3211 case DW_AT_prototyped:
3212 case DW_AT_pure:
3213 case DW_AT_ranges:
3214 case DW_AT_recursive:
3215 case DW_AT_return_addr:
3216 case DW_AT_segment:
3217 case DW_AT_specification:
3218 case DW_AT_start_scope:
3219 case DW_AT_static_link:
3220 case DW_AT_trampoline:
3221 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003222 case DW_AT_vtable_elem_location:
3223 case DW_AT_abstract_origin:
3224 case DW_AT_description:
3225 case DW_AT_sibling:
3226 break;
3227 }
3228 }
3229 }
Greg Clayton24739922010-10-13 03:15:28 +00003230 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003231
Greg Clayton24739922010-10-13 03:15:28 +00003232 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Claytonc93237c2010-10-01 20:48:32 +00003233
Greg Clayton24739922010-10-13 03:15:28 +00003234 clang_type_t return_clang_type = NULL;
3235 Type *func_type = NULL;
3236
3237 if (type_die_offset != DW_INVALID_OFFSET)
3238 func_type = ResolveTypeUID(type_die_offset);
Greg Claytonf51de672010-10-01 02:31:07 +00003239
Greg Clayton24739922010-10-13 03:15:28 +00003240 if (func_type)
Greg Clayton526e5af2010-11-13 03:52:47 +00003241 return_clang_type = func_type->GetClangLayoutType();
Greg Clayton24739922010-10-13 03:15:28 +00003242 else
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003243 return_clang_type = ast.GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003244
Greg Claytonf51de672010-10-01 02:31:07 +00003245
Greg Clayton24739922010-10-13 03:15:28 +00003246 std::vector<clang_type_t> function_param_types;
3247 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003248
Greg Clayton24739922010-10-13 03:15:28 +00003249 // Parse the function children for the parameters
3250 if (die->HasChildren())
3251 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003252 bool skip_artificial = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003253 ParseChildParameters (sc,
3254 type_sp,
3255 dwarf_cu,
3256 die,
3257 skip_artificial,
3258 type_list,
3259 function_param_types,
3260 function_param_decls);
Greg Clayton24739922010-10-13 03:15:28 +00003261 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003262
Greg Clayton24739922010-10-13 03:15:28 +00003263 // clang_type will get the function prototype clang type after this call
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003264 clang_type = ast.CreateFunctionType (return_clang_type,
3265 &function_param_types[0],
3266 function_param_types.size(),
3267 is_variadic,
3268 type_quals);
3269
Greg Clayton24739922010-10-13 03:15:28 +00003270 if (type_name_cstr)
3271 {
3272 bool type_handled = false;
3273 const DWARFDebugInfoEntry *parent_die = die->GetParent();
3274 if (tag == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003275 {
Greg Clayton24739922010-10-13 03:15:28 +00003276 if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+'))
Greg Clayton0fffff52010-09-24 05:15:53 +00003277 {
Greg Clayton24739922010-10-13 03:15:28 +00003278 // We need to find the DW_TAG_class_type or
3279 // DW_TAG_struct_type by name so we can add this
3280 // as a member function of the class.
3281 const char *class_name_start = type_name_cstr + 2;
3282 const char *class_name_end = ::strchr (class_name_start, ' ');
3283 SymbolContext empty_sc;
3284 clang_type_t class_opaque_type = NULL;
3285 if (class_name_start < class_name_end)
Greg Clayton0fffff52010-09-24 05:15:53 +00003286 {
Greg Clayton24739922010-10-13 03:15:28 +00003287 ConstString class_name (class_name_start, class_name_end - class_name_start);
3288 TypeList types;
3289 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
3290 if (match_count > 0)
Greg Clayton0fffff52010-09-24 05:15:53 +00003291 {
Greg Clayton24739922010-10-13 03:15:28 +00003292 for (uint32_t i=0; i<match_count; ++i)
Greg Clayton0fffff52010-09-24 05:15:53 +00003293 {
Greg Clayton24739922010-10-13 03:15:28 +00003294 Type *type = types.GetTypeAtIndex (i).get();
3295 clang_type_t type_clang_forward_type = type->GetClangForwardType();
3296 if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003297 {
Greg Clayton24739922010-10-13 03:15:28 +00003298 class_opaque_type = type_clang_forward_type;
3299 break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003300 }
3301 }
3302 }
Greg Clayton24739922010-10-13 03:15:28 +00003303 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003304
Greg Clayton24739922010-10-13 03:15:28 +00003305 if (class_opaque_type)
3306 {
3307 // If accessibility isn't set to anything valid, assume public for
3308 // now...
3309 if (accessibility == eAccessNone)
3310 accessibility = eAccessPublic;
3311
3312 clang::ObjCMethodDecl *objc_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003313 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
3314 type_name_cstr,
3315 clang_type,
3316 accessibility);
Greg Clayton24739922010-10-13 03:15:28 +00003317 type_handled = objc_method_decl != NULL;
3318 }
3319 }
3320 else if (parent_die->Tag() == DW_TAG_class_type ||
3321 parent_die->Tag() == DW_TAG_structure_type)
3322 {
3323 // Look at the parent of this DIE and see if is is
3324 // a class or struct and see if this is actually a
3325 // C++ method
3326 Type *class_type = ResolveType (dwarf_cu, parent_die);
3327 if (class_type)
3328 {
3329 clang_type_t class_opaque_type = class_type->GetClangForwardType();
3330 if (ClangASTContext::IsCXXClassType (class_opaque_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003331 {
Greg Clayton24739922010-10-13 03:15:28 +00003332 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
3333 // in the DWARF for C++ methods... Default to public for now...
Greg Clayton6d01ad92010-09-29 01:57:37 +00003334 if (accessibility == eAccessNone)
3335 accessibility = eAccessPublic;
3336
Greg Clayton24739922010-10-13 03:15:28 +00003337 clang::CXXMethodDecl *cxx_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003338 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
3339 type_name_cstr,
3340 clang_type,
3341 accessibility,
3342 is_virtual,
3343 is_static,
3344 is_inline,
3345 is_explicit);
Greg Clayton24739922010-10-13 03:15:28 +00003346 type_handled = cxx_method_decl != NULL;
Greg Clayton0fffff52010-09-24 05:15:53 +00003347 }
3348 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003349 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003350 }
Greg Clayton24739922010-10-13 03:15:28 +00003351
3352 if (!type_handled)
3353 {
3354 // We just have a function that isn't part of a class
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003355 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr,
3356 clang_type,
3357 storage,
3358 is_inline);
Greg Clayton24739922010-10-13 03:15:28 +00003359
3360 // Add the decl to our DIE to decl context map
3361 assert (function_decl);
3362 m_die_to_decl_ctx[die] = function_decl;
3363 if (!function_param_decls.empty())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003364 ast.SetFunctionParameters (function_decl,
3365 &function_param_decls.front(),
3366 function_param_decls.size());
Greg Clayton24739922010-10-13 03:15:28 +00003367 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003368 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003369 type_sp.reset( new Type (die->GetOffset(),
3370 this,
3371 type_name_const_str,
3372 0,
3373 NULL,
3374 LLDB_INVALID_UID,
3375 Type::eEncodingIsUID,
3376 &decl,
3377 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003378 Type::eResolveStateFull));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003379
Greg Clayton24739922010-10-13 03:15:28 +00003380 m_die_to_type[die] = type_sp.get();
3381 assert(type_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003382 }
3383 break;
3384
3385 case DW_TAG_array_type:
3386 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003387 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003388 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003389
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003390 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003391 int64_t first_index = 0;
3392 uint32_t byte_stride = 0;
3393 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00003394 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003395
3396 if (num_attributes > 0)
3397 {
3398 uint32_t i;
3399 for (i=0; i<num_attributes; ++i)
3400 {
3401 attr = attributes.AttributeAtIndex(i);
3402 DWARFFormValue form_value;
3403 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3404 {
3405 switch (attr)
3406 {
3407 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3408 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3409 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3410 case DW_AT_name:
3411 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003412 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003413 break;
3414
3415 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
3416 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3417 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3418 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003419 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003420 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003421 case DW_AT_allocated:
3422 case DW_AT_associated:
3423 case DW_AT_data_location:
3424 case DW_AT_description:
3425 case DW_AT_ordering:
3426 case DW_AT_start_scope:
3427 case DW_AT_visibility:
3428 case DW_AT_specification:
3429 case DW_AT_abstract_origin:
3430 case DW_AT_sibling:
3431 break;
3432 }
3433 }
3434 }
3435
Greg Claytonc93237c2010-10-01 20:48:32 +00003436 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3437
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003438 Type *element_type = ResolveTypeUID(type_die_offset);
3439
3440 if (element_type)
3441 {
3442 std::vector<uint64_t> element_orders;
3443 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00003444 // We have an array that claims to have no members, lets give it at least one member...
3445 if (element_orders.empty())
3446 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003447 if (byte_stride == 0 && bit_stride == 0)
3448 byte_stride = element_type->GetByteSize();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003449 clang_type_t array_element_type = element_type->GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003450 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3451 uint64_t num_elements = 0;
3452 std::vector<uint64_t>::const_reverse_iterator pos;
3453 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3454 for (pos = element_orders.rbegin(); pos != end; ++pos)
3455 {
3456 num_elements = *pos;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003457 clang_type = ast.CreateArrayType (array_element_type,
3458 num_elements,
3459 num_elements * array_element_bit_stride);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003460 array_element_type = clang_type;
3461 array_element_bit_stride = array_element_bit_stride * num_elements;
3462 }
3463 ConstString empty_name;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003464 type_sp.reset( new Type (die->GetOffset(),
3465 this,
3466 empty_name,
3467 array_element_bit_stride / 8,
3468 NULL,
Greg Clayton526e5af2010-11-13 03:52:47 +00003469 type_die_offset,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003470 Type::eEncodingIsUID,
3471 &decl,
3472 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003473 Type::eResolveStateFull));
3474 type_sp->SetEncodingType (element_type);
Greg Clayton594e5ed2010-09-27 21:07:38 +00003475 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003476 }
3477 }
3478 }
3479 break;
3480
Greg Clayton9b81a312010-06-12 01:20:30 +00003481 case DW_TAG_ptr_to_member_type:
3482 {
3483 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3484 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3485
Greg Claytond88d7592010-09-15 08:33:30 +00003486 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00003487
3488 if (num_attributes > 0) {
3489 uint32_t i;
3490 for (i=0; i<num_attributes; ++i)
3491 {
3492 attr = attributes.AttributeAtIndex(i);
3493 DWARFFormValue form_value;
3494 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3495 {
3496 switch (attr)
3497 {
3498 case DW_AT_type:
3499 type_die_offset = form_value.Reference(dwarf_cu); break;
3500 case DW_AT_containing_type:
3501 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3502 }
3503 }
3504 }
3505
3506 Type *pointee_type = ResolveTypeUID(type_die_offset);
3507 Type *class_type = ResolveTypeUID(containing_type_die_offset);
3508
Greg Clayton526e5af2010-11-13 03:52:47 +00003509 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
3510 clang_type_t class_clang_type = class_type->GetClangLayoutType();
Greg Clayton9b81a312010-06-12 01:20:30 +00003511
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003512 clang_type = ast.CreateMemberPointerType(pointee_clang_type,
3513 class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00003514
Greg Clayton526e5af2010-11-13 03:52:47 +00003515 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
3516 clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00003517
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003518 type_sp.reset( new Type (die->GetOffset(),
3519 this,
3520 type_name_const_str,
3521 byte_size,
3522 NULL,
3523 LLDB_INVALID_UID,
3524 Type::eEncodingIsUID,
3525 NULL,
3526 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003527 Type::eResolveStateForward));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003528 m_die_to_type[die] = type_sp.get();
Greg Clayton9b81a312010-06-12 01:20:30 +00003529 }
3530
3531 break;
3532 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003533 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00003534 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003535 break;
3536 }
3537
3538 if (type_sp.get())
3539 {
3540 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3541 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3542
3543 SymbolContextScope * symbol_context_scope = NULL;
3544 if (sc_parent_tag == DW_TAG_compile_unit)
3545 {
3546 symbol_context_scope = sc.comp_unit;
3547 }
3548 else if (sc.function != NULL)
3549 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003550 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003551 if (symbol_context_scope == NULL)
3552 symbol_context_scope = sc.function;
3553 }
3554
3555 if (symbol_context_scope != NULL)
3556 {
3557 type_sp->SetSymbolContextScope(symbol_context_scope);
3558 }
3559
3560// if (udt_sp.get())
3561// {
3562// if (is_forward_declaration)
3563// udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
3564// type_sp->SetUserDefinedType(udt_sp);
3565// }
3566
3567 if (type_sp.unique())
3568 {
3569 // We are ready to put this type into the uniqued list up at the module level
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003570 type_list->Insert (type_sp);
Greg Clayton450e3f32010-10-12 02:24:53 +00003571
Greg Clayton594e5ed2010-09-27 21:07:38 +00003572 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003573 }
3574 }
3575 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00003576 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003577 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003578 type_sp = type_list->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003579 }
3580 }
3581 return type_sp;
3582}
3583
3584size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00003585SymbolFileDWARF::ParseTypes
3586(
3587 const SymbolContext& sc,
3588 DWARFCompileUnit* dwarf_cu,
3589 const DWARFDebugInfoEntry *die,
3590 bool parse_siblings,
3591 bool parse_children
3592)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003593{
3594 size_t types_added = 0;
3595 while (die != NULL)
3596 {
3597 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003598 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003599 {
3600 if (type_is_new)
3601 ++types_added;
3602 }
3603
3604 if (parse_children && die->HasChildren())
3605 {
3606 if (die->Tag() == DW_TAG_subprogram)
3607 {
3608 SymbolContext child_sc(sc);
3609 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3610 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3611 }
3612 else
3613 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3614 }
3615
3616 if (parse_siblings)
3617 die = die->GetSibling();
3618 else
3619 die = NULL;
3620 }
3621 return types_added;
3622}
3623
3624
3625size_t
3626SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3627{
3628 assert(sc.comp_unit && sc.function);
3629 size_t functions_added = 0;
3630 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3631 if (dwarf_cu)
3632 {
3633 dw_offset_t function_die_offset = sc.function->GetID();
3634 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3635 if (function_die)
3636 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003637 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003638 }
3639 }
3640
3641 return functions_added;
3642}
3643
3644
3645size_t
3646SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3647{
3648 // At least a compile unit must be valid
3649 assert(sc.comp_unit);
3650 size_t types_added = 0;
3651 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3652 if (dwarf_cu)
3653 {
3654 if (sc.function)
3655 {
3656 dw_offset_t function_die_offset = sc.function->GetID();
3657 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3658 if (func_die && func_die->HasChildren())
3659 {
3660 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3661 }
3662 }
3663 else
3664 {
3665 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3666 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3667 {
3668 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3669 }
3670 }
3671 }
3672
3673 return types_added;
3674}
3675
3676size_t
3677SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3678{
3679 if (sc.comp_unit != NULL)
3680 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00003681 DWARFDebugInfo* info = DebugInfo();
3682 if (info == NULL)
3683 return 0;
3684
3685 uint32_t cu_idx = UINT32_MAX;
3686 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003687
3688 if (dwarf_cu == NULL)
3689 return 0;
3690
3691 if (sc.function)
3692 {
3693 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00003694
3695 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
3696 assert (func_lo_pc != DW_INVALID_ADDRESS);
3697
3698 return ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003699 }
3700 else if (sc.comp_unit)
3701 {
3702 uint32_t vars_added = 0;
3703 VariableListSP variables (sc.comp_unit->GetVariableList(false));
3704
3705 if (variables.get() == NULL)
3706 {
3707 variables.reset(new VariableList());
3708 sc.comp_unit->SetVariableList(variables);
3709
3710 // Index if we already haven't to make sure the compile units
3711 // get indexed and make their global DIE index list
3712 if (!m_indexed)
3713 Index ();
3714
Greg Claytonc685f8e2010-09-15 04:15:46 +00003715 std::vector<NameToDIE::Info> global_die_info_array;
Greg Clayton4b3dc102010-11-01 20:32:12 +00003716 const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (cu_idx, global_die_info_array);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003717 for (size_t idx=0; idx<num_globals; ++idx)
3718 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00003719 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 +00003720 if (var_sp)
3721 {
3722 variables->AddVariable(var_sp);
3723 ++vars_added;
3724 }
3725 }
3726 }
3727 return vars_added;
3728 }
3729 }
3730 return 0;
3731}
3732
3733
3734VariableSP
3735SymbolFileDWARF::ParseVariableDIE
3736(
3737 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003738 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00003739 const DWARFDebugInfoEntry *die,
3740 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003741)
3742{
3743
3744 VariableSP var_sp;
3745
3746 const dw_tag_t tag = die->Tag();
3747 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003748 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003749 if (num_attributes > 0)
3750 {
3751 const char *name = NULL;
Greg Claytona134cc12010-09-13 02:37:44 +00003752 const char *mangled = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003753 Declaration decl;
3754 uint32_t i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003755 Type *var_type = NULL;
3756 DWARFExpression location;
3757 bool is_external = false;
3758 bool is_artificial = false;
Sean Callananc7fbf732010-08-06 00:32:49 +00003759 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003760
3761 for (i=0; i<num_attributes; ++i)
3762 {
3763 dw_attr_t attr = attributes.AttributeAtIndex(i);
3764 DWARFFormValue form_value;
3765 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3766 {
3767 switch (attr)
3768 {
3769 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3770 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3771 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3772 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Claytona134cc12010-09-13 02:37:44 +00003773 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton594e5ed2010-09-27 21:07:38 +00003774 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003775 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
3776 case DW_AT_location:
3777 {
3778 if (form_value.BlockData())
3779 {
3780 const DataExtractor& debug_info_data = get_debug_info_data();
3781
3782 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3783 uint32_t block_length = form_value.Unsigned();
Greg Clayton016a95e2010-09-14 02:20:48 +00003784 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003785 }
3786 else
3787 {
3788 const DataExtractor& debug_loc_data = get_debug_loc_data();
3789 const dw_offset_t debug_loc_offset = form_value.Unsigned();
3790
3791 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
3792 if (loc_list_length > 0)
3793 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003794 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
3795 assert (func_low_pc != LLDB_INVALID_ADDRESS);
3796 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003797 }
3798 }
3799 }
3800 break;
3801
3802 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003803 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003804 case DW_AT_const_value:
3805 case DW_AT_declaration:
3806 case DW_AT_description:
3807 case DW_AT_endianity:
3808 case DW_AT_segment:
3809 case DW_AT_start_scope:
3810 case DW_AT_visibility:
3811 default:
3812 case DW_AT_abstract_origin:
3813 case DW_AT_sibling:
3814 case DW_AT_specification:
3815 break;
3816 }
3817 }
3818 }
3819
3820 if (location.IsValid())
3821 {
3822 assert(var_type != DIE_IS_BEING_PARSED);
3823
Greg Claytona134cc12010-09-13 02:37:44 +00003824 ConstString var_name;
3825 if (mangled)
3826 {
3827 Mangled mangled_var_name (mangled, true);
3828 var_name = mangled_var_name.GetDemangledName();
3829 }
3830
3831 if (!var_name && name)
3832 {
3833 var_name.SetCString(name);
3834 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003835
3836 ValueType scope = eValueTypeInvalid;
3837
3838 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3839 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3840
3841 if (tag == DW_TAG_formal_parameter)
3842 scope = eValueTypeVariableArgument;
3843 else if (is_external || parent_tag == DW_TAG_compile_unit)
3844 scope = eValueTypeVariableGlobal;
3845 else
3846 scope = eValueTypeVariableLocal;
3847
3848 SymbolContextScope * symbol_context_scope = NULL;
3849 if (parent_tag == DW_TAG_compile_unit)
3850 {
3851 symbol_context_scope = sc.comp_unit;
3852 }
3853 else if (sc.function != NULL)
3854 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003855 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003856 if (symbol_context_scope == NULL)
3857 symbol_context_scope = sc.function;
3858 }
3859
3860 assert(symbol_context_scope != NULL);
3861 var_sp.reset (new Variable(die->GetOffset(),
3862 var_name,
3863 var_type,
3864 scope,
3865 symbol_context_scope,
3866 &decl,
3867 location,
3868 is_external,
3869 is_artificial));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003870
3871 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003872 }
3873 }
3874 return var_sp;
3875}
3876
3877size_t
3878SymbolFileDWARF::ParseVariables
3879(
3880 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003881 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00003882 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003883 const DWARFDebugInfoEntry *orig_die,
3884 bool parse_siblings,
3885 bool parse_children,
3886 VariableList* cc_variable_list
3887)
3888{
3889 if (orig_die == NULL)
3890 return 0;
3891
3892 size_t vars_added = 0;
3893 const DWARFDebugInfoEntry *die = orig_die;
3894 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
3895 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3896 VariableListSP variables;
3897 switch (parent_tag)
3898 {
3899 case DW_TAG_compile_unit:
3900 if (sc.comp_unit != NULL)
3901 {
3902 variables = sc.comp_unit->GetVariableList(false);
3903 if (variables.get() == NULL)
3904 {
3905 variables.reset(new VariableList());
3906 sc.comp_unit->SetVariableList(variables);
3907 }
3908 }
3909 else
3910 {
3911 assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
3912 vars_added = 0;
3913 }
3914 break;
3915
3916 case DW_TAG_subprogram:
3917 case DW_TAG_inlined_subroutine:
3918 case DW_TAG_lexical_block:
3919 if (sc.function != NULL)
3920 {
3921 // Check to see if we already have parsed the variables for the given scope
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003922
3923 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
3924 assert (block != NULL);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003925 variables = block->GetVariableList(false, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003926 if (variables.get() == NULL)
3927 {
3928 variables.reset(new VariableList());
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003929 block->SetVariableList(variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003930 }
3931 }
3932 else
3933 {
3934 assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
3935 vars_added = 0;
3936 }
3937 break;
3938
3939 default:
3940 assert(!"Didn't find appropriate parent DIE for variable list...");
3941 break;
3942 }
3943
3944 // We need to have a variable list at this point that we can add variables to
3945 assert(variables.get());
3946
3947 while (die != NULL)
3948 {
3949 dw_tag_t tag = die->Tag();
3950
3951 // Check to see if we have already parsed this variable or constant?
Greg Claytonbcf12172010-10-28 00:56:11 +00003952 if (m_die_to_variable_sp[die])
3953 {
3954 if (cc_variable_list)
3955 cc_variable_list->AddVariable (m_die_to_variable_sp[die]);
3956 }
3957 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003958 {
3959 // We haven't already parsed it, lets do that now.
3960 if ((tag == DW_TAG_variable) ||
3961 (tag == DW_TAG_constant) ||
3962 (tag == DW_TAG_formal_parameter && sc.function))
3963 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003964 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003965 if (var_sp)
3966 {
3967 variables->AddVariable(var_sp);
Greg Claytonbcf12172010-10-28 00:56:11 +00003968 if (cc_variable_list)
3969 cc_variable_list->AddVariable (var_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003970 ++vars_added;
3971 }
3972 }
3973 }
3974
3975 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
3976
3977 if (!skip_children && parse_children && die->HasChildren())
3978 {
Greg Claytonbcf12172010-10-28 00:56:11 +00003979 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003980 }
3981
3982 if (parse_siblings)
3983 die = die->GetSibling();
3984 else
3985 die = NULL;
3986 }
3987
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003988 return vars_added;
3989}
3990
3991//------------------------------------------------------------------
3992// PluginInterface protocol
3993//------------------------------------------------------------------
3994const char *
3995SymbolFileDWARF::GetPluginName()
3996{
3997 return "SymbolFileDWARF";
3998}
3999
4000const char *
4001SymbolFileDWARF::GetShortPluginName()
4002{
4003 return GetPluginNameStatic();
4004}
4005
4006uint32_t
4007SymbolFileDWARF::GetPluginVersion()
4008{
4009 return 1;
4010}
4011
4012void
4013SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
4014{
4015}
4016
4017Error
4018SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
4019{
4020 Error error;
4021 error.SetErrorString("No plug-in command are currently supported.");
4022 return error;
4023}
4024
4025Log *
4026SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
4027{
4028 return NULL;
4029}
4030